やりたいこと
- 管理者
- Table : Administrators
- url : localhost/admin
- ユーザ
- Table : Users
- url : localhost/user
上記の状態で、それぞれのURLにはぞれぞれのTableに存在するレコードで認証をするようにします。
やってみる
src/Application.php
で Authentication
プラグインを読み込みます。
public function bootstrap(): void
{
parent::bootstrap();
....
// 末尾に追記
$this->addPlugin('Authentication');
}
通常のやり方だと、このあと src/Application.php
の中で、middlewareに登録したり、 getAuthenticationService
したりします。
もちろんこの方法でも ifの分岐などでマルチログインは出来るのですが、個人的にどのrouteにどの認証が適用されているのか分かりにくく感じます。
Configuring Multiple Authentication Setups
今回は routes.php
に認証の設定を記述する方式を紹介します。
prefixごとに認証の設定を記述できるので、少々冗長な書き方になりますが、分かりやすくて好きです。
<?php
use App\Middleware\AccessControlMiddleware;
use Authentication\AuthenticationService;
use Authentication\Middleware\AuthenticationMiddleware;
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;
#----------------------------------------------------------------------------
# Routing
/** @var \Cake\Routing\RouteBuilder $routes */
$routes->setRouteClass(DashedRoute::class);
/**
* 管理者用のルーティング
*/
$routes->prefix('Admin', ['_namePrefix' => 'admin:'], function (RouteBuilder $routes) {
#----------------------------------------------------------------------------
# 認証の設定
$adminAuth = new AuthenticationService([
'unauthenticatedRedirect' => '/admin/auth/login',
'queryParam' => 'redirect',
]);
$adminAuth->loadIdentifier('Authentication.Password', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'Administrators',
],
]);
$adminAuth->loadAuthenticator('Authentication.Session', [
'sessionKey' => 'admin',
]);
$adminAuth->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'loginUrl' => '/admin/auth/login',
]);
$routes->registerMiddleware('admin-auth', new AuthenticationMiddleware($adminAuth));
$routes->applyMiddleware('admin-auth');
#----------------------------------------------------------------------------
# ルーティング
// ダッシュボード
$routes->get('/', ['controller' => 'Dashboard', 'action' => 'top'], 'dashboard:top');
});
/**
* ユーザ用のルーティング
*/
$routes->prefix('User', ['_namePrefix' => 'user:'], function (RouteBuilder $routes) {
#----------------------------------------------------------------------------
# 認証の設定
$userAuth = new AuthenticationService([
'unauthenticatedRedirect' => '/user/auth/login',
'queryParam' => 'redirect',
]);
$userAuth->loadIdentifier('Authentication.Password', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'Users',
],
]);
$userAuth->loadAuthenticator('Authentication.Session', [
'sessionKey' => 'user',
]);
$userAuth->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'loginUrl' => '/user/auth/login',
]);
$routes->registerMiddleware('user-auth', new AuthenticationMiddleware($userAuth));
$routes->applyMiddleware('user-auth');
#----------------------------------------------------------------------------
# ルーティング
// ダッシュボード
$routes->get('/', ['controller' => 'Dashboard', 'action' => 'top'], 'dashboard:top');
});
本来は src/Application.php
でやっている Middlewareの登録と AuthenticationServiceの定義を routes.php
でやっています。
こちらの方式であれば、 /api
が増えたときなども prefix ごとに別途定義を出来るので、 Application.php
でif文が増えるようなことにはなりません。
ここまで定義が出来れば、あとはそれぞれの Prefix に対応するNamespace以下にチュートリアルと同様のログイン用のControllerやtemplateを設置すればOKです。
おわり
最近はLaravelばかりだったので、CakePHPのリハビリを継続中です。
CakePHP3の初期のころと変わっている点も多いのですが、確実に使いやすくなっていて触っていて楽しいです。
uchida
福岡でWebエンジニアやってます。PHP, クラウド, インフラあたりが好き。