CakePHP3でプレフィックスルーティングを利用した複数認証を実装する
2018-11-02
複数の独立した認証処理を導入したWebアプリケーションをCakePHPを使って実装する方法を紹介します。
CakePHPではプレフィックスルーティングと組み合わせることで、効率的に認証の仕組みを振り分けることができます。
本記事では、CakePHP 3のインストールから、プレフィックスルーティングを利用した複数認証の実装まで、解説します。
CakePHP 3のインストール
通常どおり、以下のコマンドでCakePHP 3をインストールします。
composer create-project --prefer-dist cakephp/app my_app_name
インストールできたら、確認用の開発サーバーを起動します。
cd my_app_name
bin/cake server
http://localhost:8765/へアクセスし、アプリケーションが正常に動作していることを確認します。
プレフィックスルーティングの定義
以下のように、別々の認証が必要なまとまりをプレフィックスルーティングでまとめます。
<?php
// config/routes.php
use Cake\Routing\Route\DashedRoute;
// 認証1
Router::prefix('admin', function (RouteBuilder $routes) {
$routes->fallbacks(DashedRoute::class);
});
// 認証2
Router::prefix('member', function (RouteBuilder $routes) {
$routes->fallbacks(DashedRoute::class);
});
// 認証3
Router::prefix('user', function (RouteBuilder $routes) {
$routes->fallbacks(DashedRoute::class);
});
上記のようにして、/admin/
配下、/member/
配下、/user/
配下でそれぞれ別の認証が必要となるような実装を行います。
プレフィックスルーティングにより、それぞれのプレフィックスで参照するコントローラーの場所が変わります。
例えば、上記の定義の場合、/admin/users/edit/5
へアクセスしたとき、src/Controller/Admin/UsersController.php
のedit()
メソッドが呼ばれ、ビューファイルはsrc/Template/Admin/Users/edit.ctp
になります。
同様に、/member/dashboard
は、src/Controller/Member/DashboardController.php
のindex()
メソッドが呼ばれ、ビューファイルはsrc/Template/Member/Dashboard/index.ctp
といった感じです。
src/Controller
およびsrc/Template
にプレフィックス用のディレクトリを追加して、そこにコントローラーやビューテンプレートをまとめる、といったディレクトリ構成とルーティングになります。
このとき、ディレクトリ構成とともに、作成したコントローラーの名前空間も変わりますので、忘れないように変更しましょう。
<?php
namespace App\Controller\Admin; // <- 変更
class UsersController extends AppController {}
AppController
を定義する
プレフィックス毎にプレフィックス毎に認証処理を分けて実装するために、プレフィックスのディレクトリにAppController
を用意し、各プレフィックス配下のコントローラーはそのAppController
を継承するようにします。
例えば、src/Controller/Admin/AppController.php
を以下の内容で配置します。
<?php
namespace App\Controller\Admin;
class AppController extends \App\Controller\AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'userModel' => 'Administrators',
],
],
'storage' => ['className' => 'Session', 'key' => 'Auth.Admin'],
]);
}
}
こうすることで、このAppController
を継承したsrc/Controller/Admin/
配下のコントローラーは、administrators
テーブルの情報でのログインが必要になります。
同様に、Member
・User
プレフィックスでもAppController
を定義しましょう。
<?php
// src/Controller/Member/AppController.php
namespace App\Controller\Member;
class AppController extends \App\Controller\AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'userModel' => 'Members',
],
],
'storage' => ['className' => 'Session', 'key' => 'Auth.Member'],
]);
}
}
<?php
// src/Controller/User/AppController.php
namespace App\Controller\User;
class AppController extends \App\Controller\AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'userModel' => 'Users',
],
],
'storage' => ['className' => 'Session', 'key' => 'Auth.User'],
]);
}
}
これで、/admin/
以下はadministrators
テーブル、/member/
以下はmembers
テーブル、/user/
以下はusers
テーブルを使って認証する仕組みになりました。
一つ注意すべき点として、AuthComponent
のstorage.key
はそれぞれの認証で一意の値である必要があります。通常、上の例のように'Auth.[プレフィックス名]'
とするのがいいでしょう。
storage.key
を一意の値にすることで、各認証が独立して動くようになるため、複数の認証で同時にログインしたりすることができるようになります。
その後の実装
ここまでで、最終的に以下のような構成になりました。
src/Controller
├── Component
│ └── empty
├── Admin
│ └── AppController.php
├── Member
│ └── AppController.php
├── User
│ └── AppController.php
├── AppController.php
├── ErrorController.php
└── PagesController.php
後は、それぞれのプレフィックスディレクトリ(src/Controller/Admin/
・src/Controller/Member/
・src/Controller/User/
)の下に、それぞれのAppController
を継承したコントローラーを作成し、開発を進めていきましょう。
なお、それぞれ作成するプレフィックスディレクトリ配下のコントローラーは、プレフィックスディレクトリのAppController
と同じ名前空間になりますので、継承する際にはuse演算子を使わずに単純に以下のように書くだけでOKです。
<?php
namespace App\Controller\Admin;
class UsersController extends AppController {}
そして、参照するビューファイルはそれぞれsrc/Template/Admin/
・src/Template/Member/
・src/Template/User/
の下にいつも通り作ればOKです。
ログインやログアウト等の処理については、プレフィックスの配下で普段と同様に実装すれば問題ありません。CakePHPのドキュメントにて解説されていますので、そちらを参考にしてください。
まとめ
以上、CakePHP 3で複数の独立した認証処理を実装する方法を解説しました。
本記事ではプレフィックスルーティングを活用して管理しやすいように実装しましたが、同様の仕組みを実装すればプレフィックスルーティングなしでも実装可能かと思います。
もしCakePHPで複数の認証処理が必要な場面に出くわしましたら、ぜひ参考になさってください。