CakePHP3のAuthコンポーネントで、identify()のFindの挙動をカスタマイズする方法
<前提条件>CakePHP(3.6), MySQL(5.7.22)
例えばMySQLのusersテーブルが下記の構成だったとする:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`nickname` varchar(255) DEFAULT NULL,
`profile` text,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_users_01` (`nickname`),
KEY `idx_users_02` (`email`,`password`),
KEY `idx_users_03` (`deleted`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
deletedというカラムがミソで、値が0ならログインできて1なら退会済という意味で使っているケースを前提とする。この場合、ログイン認証をパスする際はemail, passwordが入力された値に合致し、且つdeleted=0であればログインできるという実装にしたい。
通常、Authコンポーネントのidentify()ではemailとpasswordのみを使って認証を行うように作る例が多い。つまり、こちらが今回準備したdeletedのようなカスタマイズに対応させる必要がある。
結論:finderオプションを使って解決できる
参照を基に実際コードを書くとこんな感じ:
src/Controller/AppController:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler', [
'enableBeforeRedirect' => false,
]);
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize'=> 'Controller',
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
],
'finder' => 'auth' // ←の行を追加する
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'unauthorizedRedirect' => $this->referer(),
'authError' => __('ログインしてください。')
]);
}
↑のように、authenticate内のfinderキーに対してvalueに'auth'と書いた場合、usersテーブルに対応するUsersTable.phpの中に下記を記載してあげるだけでOK。
src/Model/Table/UsersTable.php
public function findAuth(\Cake\ORM\Query $query, array $options)
{
$query->where(['Users.deleted' => 0]);
return $query;
}
こうすると、identify()実行前に↑のwhere条件を追加してからexecuteしてくれるという流れ。findAuthという関数名は前述のfinderキーに設定した'auth'というvalueと連動している。
最後まで読んでいただきありがとうございます!現在、受託的な開発で収入を得るのではなく個人開発でWebサービスを作り、収入のポートフォリオを構築していくために時間を注いでいます!もしサポートしていただけたら大変嬉しいです!