2012-04-01 14 views
9

मैं Symfony2 में एक परिवर्तन पासवर्ड सुविधा को एक साथ रखने की कोशिश कर रहा हूं। मेरे पास "वर्तमान पासवर्ड" फ़ील्ड, एक "नया पासवर्ड" फ़ील्ड और "नया पासवर्ड पुष्टि करें" फ़ील्ड है, और जिस भाग पर मैं वर्तमान में ध्यान केंद्रित कर रहा हूं वह "वर्तमान पासवर्ड" फ़ील्ड को मान्य कर रहा है।Symfony2 में एक पासवर्ड मान्य करना

(वैसे, मुझे अब एहसास है कि FOSUserBundle जैसी चीजें मौजूद हैं जो मेरे लिए इनमें से बहुत सी चीजों का ख्याल रखती हैं, लेकिन मैंने पहले ही आधिकारिक सिम्फनी दस्तावेज के आधार पर अपनी प्रमाणीकरण प्रणाली बनाई है, और मेरे पास नहीं है समय अभी मेरे सारे प्रमाणीकरण कोड को फिर से करना)

क्या मैं कल्पना कर रहा हूँ/उम्मीद कर रहा क्या कर सकते हैं एक सत्यापन कॉलबैक कि कहते हैं बनाने है कुछ इस तरह:।

// Entity/User.php 

public function currentPasswordIsValid(ExecutionContext $context) 
{ 
    $currentPassword = $whatever; // whatever the user submitted as their current password 
    $factory = $this->get('security.encoder_factory'); // Getting the factory this way doesn't work in this context. 
    $encoder = $factory->getEncoder($this); 
    $encryptedCurrentPassword = $encoder->encodePassword($this->getPassword(), $this->getSalt()); 

    if ($encyptedCurrentPassword != $this->getPassword() { 
    $context->addViolation('Current password is not valid', array(), null); 
    } 
} 

आप मेरी टिप्पणी में देख सकते हैं , उपरोक्त कोड काम नहीं करता है, कम से कम दो कारण हैं। मैं केवल उन विशेष मुद्दों के बारे में विशिष्ट प्रश्न पोस्ट करूंगा, लेकिन शायद मैं गलत पेड़ को पूरी तरह से भौंक रहा हूं। यही कारण है कि मैं समग्र सवाल पूछ रहा हूं।

तो, मैं उपयोगकर्ता के पासवर्ड को कैसे सत्यापित कर सकता हूं?

उत्तर

10

सिम्फनी 2.1 के बाद से built-in constraint है।


सबसे पहले, आपको custom validation constraint बनाना चाहिए। आप सत्यापनकर्ता को एक सेवा के रूप में पंजीकृत कर सकते हैं और जो कुछ भी आपको चाहिए उसे इंजेक्ट कर सकते हैं।

दूसरा, चूंकि आप शायद उपयोगकर्ता कक्षा में वर्तमान पासवर्ड के लिए एक फ़ील्ड जोड़ना नहीं चाहते हैं, तो बस इसे बाधा डालने के लिए, आप form model कहला सकते हैं। अनिवार्य रूप से, आप Form\Model नामस्थान में एक कक्षा बनाते हैं जिसमें वर्तमान पासवर्ड फ़ील्ड और उपयोगकर्ता ऑब्जेक्ट का संदर्भ होता है। फिर आप उस कस्टम फ़ील्ड को उस पासवर्ड फ़ील्ड पर चिपका सकते हैं। फिर आप इस फॉर्म मॉडल के खिलाफ अपना पासवर्ड चेंज फॉर्म टाइप बनाते हैं।

<?php 
namespace Vendor\Bundle\AppBundle\Validator\Constraints\User; 

use Symfony\Component\Validator\Constraint; 

/** 
* @Annotation 
*/ 
class CurrentPassword extends Constraint 
{ 
    public $message = "Your current password is not valid"; 

    /** 
    * @return string 
    */ 
    public function validatedBy() 
    { 
     return 'user.validator.current_password'; 
    } 
} 

और इसकी सत्यापनकर्ता:

यहाँ मेरी परियोजनाओं में से एक से एक बाधा का एक उदाहरण है

<?php 
namespace Vendor\Bundle\AppBundle\Validator\Constraints\User; 

use Symfony\Component\Validator\ConstraintValidator; 
use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; 
use Symfony\Component\Security\Core\SecurityContextInterface; 
use JMS\DiExtraBundle\Annotation\Validator; 
use JMS\DiExtraBundle\Annotation\InjectParams; 
use JMS\DiExtraBundle\Annotation\Inject; 

/** 
* @Validator("user.validator.current_password") 
*/ 
class CurrentPasswordValidator extends ConstraintValidator 
{ 
    /** 
    * @var EncoderFactoryInterface 
    */ 
    private $encoderFactory; 

    /** 
    * @var SecurityContextInterface 
    */ 
    private $securityContext; 

    /** 
    * @InjectParams({ 
    *  "encoderFactory" = @Inject("security.encoder_factory"), 
    *  "securityContext" = @Inject("security.context") 
    * }) 
    * 
    * @param EncoderFactoryInterface $encoderFactory 
    * @param SecurityContextInterface $securityContext 
    */ 
    public function __construct(EncoderFactoryInterface $encoderFactory, 
           SecurityContextInterface $securityContext) 
    { 
     $this->encoderFactory = $encoderFactory; 
     $this->securityContext = $securityContext; 
    } 

    /** 
    * @param string  $currentPassword 
    * @param Constraint $constraint 
    * @return boolean 
    */ 
    public function isValid($currentPassword, Constraint $constraint) 
    { 
     $currentUser = $this->securityContext->getToken()->getUser(); 
     $encoder = $this->encoderFactory->getEncoder($currentUser); 
     $isValid = $encoder->isPasswordValid(
      $currentUser->getPassword(), $currentPassword, null 
     ); 

     if (!$isValid) { 
      $this->setMessage($constraint->message); 
      return false; 
     } 

     return true; 
    } 
} 

मैं अपने Blofwish password encoder bundle उपयोग करते हैं, तो मैं तीसरा तर्क के रूप में नमक उत्तीर्ण नहीं होते हैं $encoder->isPasswordValid() विधि पर, लेकिन मुझे लगता है कि आप इस उदाहरण को अपनी आवश्यकताओं के अनुसार अनुकूलित कर सकेंगे।

इसके अलावा, मैं विकास को सरल बनाने के लिए JMSDiExtraBundle का उपयोग कर रहा हूं, लेकिन आप निश्चित रूप से शास्त्रीय सेवा कंटेनर कॉन्फ़िगरेशन तरीके का उपयोग कर सकते हैं।

+0

ठीक है, धन्यवाद। लेकिन वास्तविक पासवर्ड सत्यापन भाग के बारे में क्या? यही मेरा सवाल पूछ रहा था। मुझे पहले से ही एक कस्टम सत्यापनकर्ता बनाने और फॉर्म फ़ील्ड बनाने का तरीका पता है। –

+0

एक उदाहरण जोड़ा गया। –

+0

बहुत बढ़िया, धन्यवाद। मै उसे करने की एक कोशिश तो करूंगा। –

0

FOSUserBundleModelManager कक्षा का उपयोग करता है जो आधार Model से अलग है। आप उनके implementation देख सकते हैं।

-3

मैंने गॉर्डियन गांठ काटने का अंत किया। मैंने सिम्फनी के सभी सामानों को छोड़ दिया और नियंत्रक में सभी तर्क किए।

+1

अरे आपको नई उपयोगकर्ता पासवर्ड सत्यापन बाधा के साथ फिर से प्रयास करना चाहिए। – Acyra

6

सिम्फनी 2 में। http://symfony.com/doc/master/reference/constraints/UserPassword.html

तो उदाहरण के लिए आपके प्रपत्र बिल्डर में: 1 आप में निर्मित सत्यापनकर्ता का उपयोग कर सकते

// declare 
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; 

// mapped=>false (new in 2.1) is to let the builder know this is not an entity field 
->add('currentpassword', 'password', array('label'=>'Current password', 'mapped' => false, 'constraints' => new UserPassword())) 

जाहिर है वहाँ एक बग है अभी कि सत्यापनकर्ता के साथ ऐसा या अब काम हो सकता है हो सकता है https://github.com/symfony/symfony/issues/5460

+1

एक छोटा सा नोट, एक टाइपो है, यह 'सिम्फनी \ घटक \ सुरक्षा \ कोर \ वैलिडेटर \ बाधाएं \ उपयोगकर्ता पासवर्ड' होना चाहिए (''' बाधाओं में गायब है) – loostro

संबंधित मुद्दे