CakePHP3:現在のパスワードを確認する方法

パスワードの変更画面において「現在のパスワードを入力させ、正しいか確認する」ケースがあります。 実施するのに注意点が2つあります:

hashの同一を確認するにはDefaultPasswordHasherのhashではなくcheckを用いる

こんな感じでモデルに記述します:

$validator
    ->allowEmpty('current_password', function ($context) {
                                         return empty($context['data']['password'])
                                 })
    ->add('current_password', 'match_current_password'
          'rule'    => function ($value, $context) {
                           return (new DefaultPasswordHasher)->check($value, $user->password);
          },

DefaultPasswordHasherは同じパスワードであっても異なるハッシュが生成されますのでhashメソッドは使えません:

// 同じパスワードでもハッシュが異なるので、必ずfalseになる
return (new DefaultPasswordHasher)->hash($value) === $user->password;

パスワードのハッシュはgetやfindでは拾ってこれない

findやgetでpasswordカラムを拾ってきても中身は空っぽです:

$user = $this->user->get($context['data']['id']);
$data = $user->toArray();

// $data['password']は必ず空なのでfalseになる
return (new DefaultPasswordHasher)->check($value, $data['password']);

そのため、$user->passwordと比較する必要があります。