CakePHP 4.0.0-RC2 でユーザー認証を実装
はじめに
今日は CakePHP 4.0.0-RC2 でユーザー認証をする方法をご紹介します。
- CakePHP
- 4.0.0-RC2
- XAMPP
- 7.3.11
- PHP
- 7.3.11
- MariaDB
- 10.4.8
- OS
- Win 10 Home 64Bit
1. ユーザー情報の準備
1-1. テーブル作成
下記 SQL で users テーブルを作成します。今回はテストプログラムなので、非常にシンプルな構成です。
CREATE TABLE `users` (
`id` int(10) UNSIGNED NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `users`
ADD PRIMARY KEY (`id`),
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
1-2. ユーザー関連機能を Bake
テスト用ユーザーを登録するためにフォームを作成します。
今回は bake all で生成しました。
> cd \path\to\cakephp4
> bin\cake bake all users
1-3. パスワードのハッシュ化
上記 Bake で生成したフォームから登録すると、パスワードが平文になってしまいます。
エンティティに下記を追加し、ハッシュ化して保存するようにします。
<?php
declare(strict_types=1);
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher; // ← これを追加
use Cake\ORM\Entity;
class User extends Entity
{
// ~~~省略~~~
// ↓これを追加
protected function _setPassword(string $password)
{
if (strlen($password) === 0) {
return null;
}
return (new DefaultPasswordHasher)->hash($password);
}
}
1-4. ユーザー情報の登録
Bake で生成したユーザー登録画面を開き、テスト用ユーザーを登録してください。
URL は https://example.com/users/add のような感じです。
2. authentication プラグインはまだ使えず
CakePHP 4 からは AuthComponent は非推奨になり、代わりに cakephp/authentication プラグインの使用が望ましいとされています。
- AuthComponent - 3.8 (CakePHP 3 Cookbook)
- https://book.cakephp.org/3/ja/controllers/components/authentication.html
- GitHub - cakephp/authentication: Authentication plugin for CakePHP. Can also be used in PSR7 based applications.
- https://github.com/cakephp/authentication
しかし comopser でインストールしようとしたら、エラーになりました。
> composer require cakephp/authentication
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for cakephp/authentication ^1.4 -> satisfiable by cakephp/authentication[1.4.0].
- Conclusion: remove cakephp/cakephp 4.x-dev
- Conclusion: don't install cakephp/cakephp 4.x-dev
- cakephp/authentication 1.4.0 requires cakephp/core ^3.7 -> satisfiable by cakephp/core[3.7.0, 3.7.0-RC1, 3.7.0-RC2, 3.7.0-RC3, 3.7.0-beta1, 3.7.1, 3.7.2, 3.7.3, 3.7.4, 3.7.5, 3.7.6, 3.7.7, 3.7.8, 3.7.9, 3.8.0, 3.8.0-RC1, 3.8.0-RC2, 3.8.0-RC3, 3.8.0-beta1, 3.8.1, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6].
~~~省略~~~
無理やりインストールする方法もあるのかな、とも思ったのですが、今回は AuthComponent で実装することにしました。
3. 従来の AuthComponent で実装
3-1. AppController で AuthComponent 読込み
参考にしたのは CakePHP 3 のドキュメントです。
- 認証(ログインとログアウト) (CakePHP 3 Cookbook)
- https://book.cakephp.org/3/ja/tutorials-and-examples/blog-auth-example/auth.html#id3
AppController の initialize() に下記を追加します。
public function initialize(): void
{
// ~~~ 省略 ~~~
// これを追加
$this->loadComponent('Auth', [
// ログイン後に遷移するアクション
'loginRedirect' => [
'controller' => 'Pages',
'action' => 'home'
],
// ログアウトした後に遷移するアクション
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
]
]);
}
3-2. UsersController に設定と login / logout アクションを追加
UsersController に下記を追記します。今回は Users コントローラの logout アクションのみ許可しています。
公式ドキュメントによると、ログイン不要なアクションを指定する $this->Auth->allow() には login アクションを含めてはいけません。
<?php
declare(strict_types=1);
namespace App\Controller;
use Cake\Event\EventInterface; // ←これを追加。ドキュメントと異なるので注意
class UsersController extends AppController
{
// これを追加。引数の型が EventInterface なので注意
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
// ログインなしでアクセスできるアクション
$this->Auth->allow(['logout']);
}
// ~~~ 省略 ~~~
}
上記コードを CakePHP 3 のドキュメント通りに、use \Cake\Event\Event; で実装したら下記エラーがでました。このメッセージに従い EventInterface に変更しています。
Declaration of App\Controller\UsersController::beforeFilter(Cake\Event\Event $event) should be compatible with Cake\Controller\Controller::beforeFilter(Cake\Event\EventInterface $event)
次に、同じく UsersController に、下記 login() と logout() のアクションを追加します。
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
3-3. ログイン画面のテンプレートを追加
最後に template/Users に 下記 login.php を追加します。
<?= $this->Flash->render() ?>
<?= $this->Form->create() ?>
<h1><?= __('Please enter your username and password') ?></h1>
<div>
<?= $this->Form->control('username') ?>
<?= $this->Form->control('password') ?>
</div>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
これで実装は完了です。https://example.com/ などにアクセスし、ログイン画面に遷移することと、登録したユーザー情報でログインできるか試してみてください。
4. おわりに
CakePHP 4 のユーザー認証では authentication プラグインが推奨されていますが、composer でのインストールはまだ出来ませんでした。
Auth コンポーネントによる認証は、CakePHP 3 用コードの大部分を流用することができました。CakePHP 3 から 4 への移行を少しでも早く終わらせたい場合には、Auth コンポーネントによる認証であれば短時間で実装できそうです。