
Cake2からCake4の移行の際、ログインパスワードの保存をしているハッシュ化されたデータはCake2では、sha1方式で保存されていると思います。
なので、セキュリティ面からCake4のデフォルトであるbcryptの方式で保存しなおすという作業の必要が出てくるかと思います。
■ Cakephp4: ハッシュ化のアルゴリズムの変更
https://book.cakephp.org/4/ja/controllers/components/authentication.html#id17
例えば、ログイン画面からログインした際、すでにCake2で保存されているハッシュ値はsha1という方式なので、新たなリハッシュが必要になります。
公式マニュアルにも記載されてますが、needsPasswordRehash() という新たにリハッシュが必要かどうかのbool値を返してくれる便利なメソッドが用意されています。
$this->Auth->authenticationProvider()->needsPasswordRehash()
今回、自分が陥った罠は、別アクションにて、すでに(sha1で)保存されているパスワードの整合性チェックをする場合、Cake2とCake4でチェックの仕方が異なるので、事前にリハッシュを施さなければならない状況になりました。そこで、needsPasswordRehash() を利用しようとすると、
error
error: [Error] Call to a member function needsPasswordRehash() on null
というエラーがでました。
よくよく考えてみると、導線的にはユーザーのログイン時にリハッシュするかどうかの判定があるだけでよいはず。(ログイン時に古い暗号形式であれば、リハッシュして保存更新する)
なので、ログイン後には新たなハッシュ値で統一されている形になるはずで、別アクションでは needsPasswordRehash() を利用する場面はなさそう。。ということに気づきました)汗
なので、マニュアル通りに
use Cake\Auth\DefaultPasswordHasher;
// コントローラクラス内にて
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
if ($this->Auth->authenticationProvider()->needsPasswordRehash()) {
$user = $this->Users->get($this->Auth->user('id'));
$user->password = (new DefaultPasswordHasher())->hash($this->getRequest()->getData('password'));
$this->Users->save($user);
}
return $this->redirect($this->Auth->redirectUrl());
}
}
}
という形で、needsPasswordRehash() は $this->Auth->setUser($user); 後に判定してやると期待通りに動作します。