AuthenticationMiddleware
の挙動が把握できておらず、ハマったのでメモ
AuthenticationMiddleware
の挙動
チュートリアル に
// src/Application.php public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { $middlewareQueue // 〜 ->add(new AuthenticationMiddleware($this)); // 〜 } public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface { // 〜 $authenticationService->loadAuthenticator('Authentication.Session'); $authenticationService->loadAuthenticator('Authentication.Form', [ // 〜 ]); // 〜 }
// UsersController public function login() { // 〜 略 〜 $result = $this->Authentication->getResult(); // 〜 略 〜 }
このようなサンプルがあるが、getResult()
までの流れはこのようになっている
getResult()
の Result はミドルウェアの段階でセットされるAuthenticationMiddleware
でSessionAuthenticator
->FormAuthenticator
の順で認証して、認証できた時点で Result が Success になる- ログイン中は
FormAuthenticator
は実行されない (username + password による認証は行われない)
今回やりたかった事
- ログイン中であっても username + password による再認証を行いたい
実現方法
- login アクション内 で
FormAuthenticator
を取得してusername + password
による認証を行う
サンプル
public function login() { /** @var AuthenticationComponent $authenticationComponent */ $authenticationComponent = $this->Authentication; // 既存のセッションを削除 $authenticationComponent->logout(); /** @var AuthenticationService $authenticationService */ $authenticationService = $authenticationComponent->getAuthenticationService(); $authenticators = $authenticationService->authenticators(); // FormAuthenticator を取得 $formAuthenticator = null; foreach ($authenticators as $authenticator) { if ($authenticator instanceof FormAuthenticator) { $formAuthenticator = $authenticator; } } if (is_null($formAuthenticator)) { throw new \Exception(); } // FormAuthenticator で username + password による認証を行い、セッションを生成 /** @var FormAuthenticator $formAuthenticator */ $authenticate = $formAuthenticator->authenticate($this->_request()); if (!$authenticate->isValid()) { // 適宜 } $authenticationComponent->setIdentity($authenticate->getData()); // 〜 }