LoginSignup
8
4

More than 5 years have passed since last update.

CakePHP3.6 にて AuthenticationMiddleware 試験導入

Last updated at Posted at 2018-09-25

CakePHP3.6にてAuthenticationMiddlewareを試してみた結果です。

インストールは以下サイトを参考に行いました。

cakephp/authentication

Composerには以下の2つを追加

  • "cakephp/authentication": "^1.0"
  • "firebase/php-jwt": "^5.0"

その他に私の設定では php-ldap を追加インストールする必要がありました。

Application.php 抜粋

Application.php
<?php
namespace App;

use Cake\Http\BaseApplication;
use Cake\Routing\Router;
use Authentication\Middleware\AuthenticationMiddleware;
use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceProviderInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class Application extends BaseApplication implements AuthenticationServiceProviderInterface
{
    public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response)
    {
        $service = new AuthenticationService();
        $service->loadIdentifier('Authentication.Password',
            [
                'fields' => [
                    'username' => 'email',
                    'password' => 'password',
                ],
                'resolver' => [
                    'className' => 'Authentication.Orm',
                    'finder' => 'auth'
                ]
            ]
        );
        $service->loadAuthenticator('Authentication.Session');
        $service->loadAuthenticator('Authentication.Form', [
            'fields' => [
                'username' => 'email',
                'password' => 'password'
            ],
            //'loginUrl' => '/users/login' //指定すると何故かエラー。
            //'loginUrl' => ['controller' => 'users', 'action' => 'login'] //これもエラー
        ]);
        return $service;
    }


    public function bootstrap()
    {
        parent::bootstrap();
        $this->addPlugin('Authentication');
    }

    public function middleware($middlewareQueue)
    {
        $authentication = new AuthenticationMiddleware($this, [
            'unauthenticatedRedirect' =>'/',
            'queryParam' => null,
        ]);
        $middlewareQueue->add($authentication);
        return $middlewareQueue;
    }
}

AppController.php 抜粋

AppController.php
<?php
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Security');
        $this->loadComponent('Flash');
        $this->loadComponent('RequestHandler', [
            'enableBeforeRedirect' => false,
        ]);
        $this->loadComponent('Authentication.Authentication', [
            'logoutRedirect' => '/users/login',  // Default is false
            'requireIdentity' => true
        ]);
    }
}

UsersController.php 抜粋

UsersController.php
<?php

namespace App\Controller;
use Cake\Core\Configure;
use Cake\Event\Event;
use Cake\Http\Exception\InternalErrorException;
use Cake\Mailer\Email;
use Cake\I18n\FrozenTime;
use App\Controller\AppController;
use App\Model\Entity\User;

class UsersController extends AppController
{
    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->Authentication->allowUnauthenticated(['login', 'add', 'forgot', 'resetPassword', 'confirm']);
    }

    public function login()
    {
        $result = $this->Authentication->getResult();
        if ($result->isValid()) {
            $redirect = $this->request->getQuery('redirect', ['controller' => 'users', 'action' => 'top']);
            return $this->redirect($redirect);
        }
        if ($this->request->is(['post']) && !$result->isValid()) {
            $this->Flash->error(__('User name or password is incorrect'));
        }
    }

    public function top()
    {
        $this->set('user_name', $this->Authentication->getIdentity()->user_name);
    }

    public function logout()
    {
        $this->Authentication->logout();
        $this->Flash->success(__('Logged out.'));
        //設定でリダイレクト先を書いたが動作しないので改めて、ここで指定。
        return $this->redirect(['controller' => 'users', 'action' => 'login']);
    }
}

気になる点

  • コンポーネントで logoutRedirect を指定するがリダイレクトしない。
  • Authentication.Form にて loginUrl を指定するとエラー。

Chinpeiさん指南のもと以下は克服しました。ありがとうございました。

chinpei215
色々聞いてみました。少なくとも一点目の問題は解決しているかもしれません。 requireIdentity は true のままがよさそうです。これがアクションのアクセス可否を制御します。ただし、AuthComponent と違って login も allowUnauthenticated() に列挙する必要があるみたいです。

上記設定でログインはできるが、許可していないページも表示されてしまう。

雑感

  • ミドルウエアと共にAuthenticationコンポーネントを入れなくては使えない。
  • 設定が多岐に渡り複雑。
  • DebagKit も範疇外なので動作確認も不便。(使い方が間違っていだけかも知れません^^;)

結果的にはAuthコンポーネントだけ動作する認証管理の方が簡単かも!?

解釈が違っていたらごめんなさい。
やっぱりミドルウエアの方が良いんだよ〜みたいな意見がありましたら是非お願いします。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4