2012-04-01 11 views
9

私はSymfony2にパスワード変更機能を組み込もうとしています。 「現在のパスワード」フィールド、「新しいパスワード」フィールド、「新しいパスワードの確認」フィールドがあり、現在注目しているのは「現在のパスワード」フィールドの検証です。symfony2のパスワードを確認する

(ところで、FOSUserBundleのようなものが存在していることがわかりましたが、すでに公式のSymfonyのドキュメントに基づいて認証システムを構築しています今の時間はすべての私の認証コードをやり直す)

は、私は私が行うことができます願って/想像してることは言う検証コールバックを作成している。このような何か:あなたは私のコメントで見ることができるように

// 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); 
    } 
} 

上記のコードがうまくいかない理由が少なくとも2つあります。私はそれらの特定の問題に関する特定の質問を投稿するだけですが、おそらく私は間違ったツリー全体を吠えているかもしれません。だからこそ私は全体的な質問をしている。

どのようにしてユーザーのパスワードを検証できますか?

答えて

10

Symfony 2.1以来、built-in constraintがあります。


まず、custom validation constraintを作成する必要があります。バリデーターをサービスとして登録し、必要なものを注入することができます。

第2に、現在のパスワードのフィールドをUserクラスに追加するだけで、制約を適用する必要がないため、form modelという名前を使用できます。基本的には、現在のパスワードフィールドとユーザーオブジェクトへの参照を保持するクラスを名前空間Form\Modelに作成します。あなたはそのパスワードフィールドにカスタム制約を張ることができます。次に、このフォームモデルに対してパスワード変更フォームタイプを作成します。ここで

は私のプロジェクトの1からの制約の例です:

<?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'; 
    } 
} 

とそのバリ:私は私のBlofwish password encoder bundleを使用するので、私は3番目の引数として塩を渡さない

<?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; 
    } 
} 

$encoder->isPasswordValid()メソッドに追加しましたが、この例を自分のニーズに合わせて自分で調整できると思います。

また、開発を簡略化するためにJMSDiExtraBundleを使用していますが、もちろん古典的なサービスコンテナの設定方法を使用することもできます。

+0

よかった、ありがとう。しかし、実際のパスワード検証部分はどうですか?それは私の質問が求めていたものです。カスタムバリデータの作成方法とフォームフィールドの作成方法はすでに知っています。 –

+0

例を追加しました。 –

+0

素晴らしいです、ありがとうございます。私はそれを試してみましょう。 –

0

FOSUserBundleは、Modelとは別のModelManagerクラスを使用します。 implementationを確認できます。

-3

私はゴルドの結び目を切ってしまった。私はSymfonyのフォームのすべてをバイパスし、コントローラ内のすべてのロジックを実行しました。

+1

新しいUserPassword検証制約をもう一度試してみてください。 – Acyra

6

In Symfony 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

小さなメモ、タイプミスがあります。これは 'Symfony \ Component \ Security \ Core \ Validator \ Constraints \ UserPassword'です(Contraintsに' s'がありません) – loostro

関連する問題