HOME > > > >

認証

インストール

CakePHP4xではAuthComponentからミドルウェアでの認証へと移行される。 authenticationはプラグインとして提供されているのでcomposerでインストールする。

  1. php composer.phar require cakephp/authentication

認証用モデルの設定

認証用のエンティティにパスワード暗号化のロジックを追加

  1. <?php
  2. // 追加
  3. use Authentication\PasswordHasher\DefaultPasswordHasher;
  4.  
  5. class Manager extends Entity
  6. {
  7.     // 追加
  8.     protected function _setPassword(string $password) : ?string
  9.     {
  10.         if (strlen($password) > 0) {
  11.             return (new DefaultPasswordHasher())->hash($password);
  12.         }
  13.     }
  14. }
  15. ?>

ミドルウェアの設定

デフォルトの認証用のモデルはUsersのemail、passwordを利用する。変更する場合は Authentication.Passwordのresolver、fieldsで設定する。

src/Application.php

  1. <?php
  2. declare(strict_types=1);
  3.  
  4. namespace App;
  5.  
  6. use Cake\Core\Configure;
  7. use Cake\Core\Exception\MissingPluginException;
  8. use Cake\Error\Middleware\ErrorHandlerMiddleware;
  9. use Cake\Http\BaseApplication;
  10. use Cake\Http\MiddlewareQueue;
  11. use Cake\Routing\Middleware\AssetMiddleware;
  12. use Cake\Routing\Middleware\RoutingMiddleware;
  13.  
  14. // 認証用のクラス、インターフェイスのインポート
  15. use Authentication\AuthenticationService;
  16. use Authentication\AuthenticationServiceInterface;
  17. use Authentication\AuthenticationServiceProviderInterface;
  18. use Authentication\Middleware\AuthenticationMiddleware;
  19. use Cake\Routing\Router;
  20. use Psr\Http\Message\ServerRequestInterface;
  21.  
  22. // インターフェイスを継承する
  23. class Application extends BaseApplication implements AuthenticationServiceProviderInterface
  24. {
  25.  
  26.     // ルーティングのミドルウェアを読み込んだあとに
  27.     // 認証のミドルウェアを追加する
  28.     // ->add(new AuthenticationMiddleware($this)
  29.    
  30.     public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
  31.     {
  32.         $middlewareQueue
  33.             // Catch any exceptions in the lower layers,
  34.             // and make an error page/response
  35.             ->add(new ErrorHandlerMiddleware(Configure::read('Error')))
  36.  
  37.             // Handle plugin/theme assets like CakePHP normally does.
  38.             ->add(
  39.                 new AssetMiddleware(
  40.                     [
  41.                         'cacheTime' => Configure::read('Asset.cacheTime'),
  42.                     ]
  43.                 )
  44.             )
  45.  
  46.             // Add routing middleware.
  47.             // If you have a large number of routes connected, turning on routes
  48.             // caching in production could improve performance. For that when
  49.             // creating the middleware instance specify the cache config name by
  50.             // using it's second constructor argument:
  51.             // `new RoutingMiddleware($this, '_cake_routes_')`
  52.             ->add(new RoutingMiddleware($this))
  53.  
  54.             // 認証のミドルウェア追加
  55.             ->add(new AuthenticationMiddleware($this));
  56.  
  57.         return $middlewareQueue;
  58.     }
  59.  
  60.  
  61.     /**
  62.      * インターフェイスの実装
  63.      *
  64.      * @param ServerRequestInterface $request
  65.      * @return AuthenticationServiceInterface
  66.      */
  67.     public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
  68.     {
  69.         $login_url = Router::url([
  70.             'controller' => 'Pages',
  71.             'action'     => 'login',
  72.         ]);
  73.  
  74.         $service = new AuthenticationService([
  75.             'unauthenticatedRedirect' => $login_url,
  76.             'queryParam'              => 'redirect',
  77.         ]);
  78.  
  79.         // identifiers を読み込み、email と password のフィールドを確認します
  80.         // 認証用のモデルの設定
  81.         $service->loadIdentifier(
  82.             'Authentication.Password',
  83.             [
  84.                 'resolver' => [
  85.                     'className' => 'Authentication.Orm',
  86.                     'userModel' => 'Managers',
  87.                 ],
  88.                 'fields'   => [
  89.                     'username' => 'mail',
  90.                     'password' => 'password',
  91.                 ],
  92.             ]
  93.         );
  94.  
  95.         // authenticatorsをロードしたら, 最初にセッションが必要です
  96.         $service->loadAuthenticator('Authentication.Session');
  97.  
  98.         // 入力した email と password をチェックする為のフォームデータを設定します
  99.         $service->loadAuthenticator(
  100.             'Authentication.Form',
  101.             [
  102.                 'fields'   => [
  103.                     'username' => 'mail',
  104.                     'password' => 'password',
  105.                 ],
  106.                 'loginUrl' => $login_url,
  107.             ]
  108.         );
  109.  
  110.         return $service;
  111.     }
  112. }
  113. ?>

コントローラー、ビューの設定

AppController.php

  1. <?php
  2. class AppController extends Controller
  3. {
  4.     // $this->loadComponent('Authentication.Authentication');
  5.     public function initialize(): void
  6.     {
  7.         parent::initialize();
  8.  
  9.         $this->loadComponent('RequestHandler');
  10.         $this->loadComponent('Flash');
  11.  
  12.         // 認証結果を確認し、サイトのロックを行うために次の行を追加します
  13.         $this->loadComponent('Authentication.Authentication');
  14.     }
  15. }
  16. ?>

ログインページやログインが不要なページがあるコントローラーでは beforeFilterのaddUnauthenticatedActions()でログイン不要のアクションを設定する。

  1. <?php
  2. class PagesController extends AppController
  3. {
  4.  
  5.     public function beforeFilter(EventInterface $event)
  6.     {
  7.         parent::beforeFilter($event);
  8.         // 認証が必要ないアクションの設定
  9.         $this->Authentication->addUnauthenticatedActions(['login']);
  10.     }
  11.  
  12.     public function home()
  13.     {
  14.         // ログイン後表示されるページ
  15.     }
  16.  
  17.     // ログインページ
  18.     public function login()
  19.     {
  20.         $this->request->allowMethod(['get', 'post']);
  21.         $result = $this->Authentication->getResult();
  22.         // POST, GET を問わず、ユーザーがログインしている場合はリダイレクトします
  23.         if ($result->isValid()) {
  24.             // 認証が成功した場合に表示するページ「
  25.             $redirect = $this->request->getQuery('redirect', [
  26.                     'controller' => 'Pages',
  27.                     'action'     => 'home',
  28.                 ]);
  29.  
  30.             return $this->redirect($redirect);
  31.         }
  32.         // ユーザーが submit 後、認証失敗した場合は、エラーを表示します
  33.         if ($this->request->is('post') && !$result->isValid()) {
  34.             $this->Flash->error(__('Invalid username or password'));
  35.         }
  36.     }
  37. }
  38. ?>

templates/Pages/login.php

  1.  
  2. <div class="managers form">
  3.     <?= $this->Flash->render() ?>
  4.     <h3>Login</h3>
  5.     <?= $this->Form->create() ?>
  6.     <fieldset>
  7.         <legend><?= __('Please enter your username and password') ?></legend>
  8.         <?= $this->Form->control('mail', ['required' => true]) ?>
  9.         <?= $this->Form->control('password', ['required' => true]) ?>
  10.     </fieldset>
  11.     <?= $this->Form->submit(__('Login')); ?>
  12.     <?= $this->Form->end() ?>
  13. </div>
  14.  

参照ページ