CakePHP5入門【CakePHP5認証編①】一般的な認証
A子
ログイン認証の機能を作らないとダメじゃん
それって簡単に作れるものなの?
B美
C菜
B美
A子
(公式ページなのは同じだけど…)
C菜の示した日本語のページのほうが良いんだけど…
C菜
バージョンが違いますよ~
B美
最新バージョンである「3.x」って、まだ日本語には翻訳されてないのよね(苦笑)
さらに言えば、CakePHP5の認証サンプルであるこちらのページについても、実は古い認証バージョン(2.x)のほうで書かれているわ
(クリックすると別ウィンドウで開きます)
※2025年3月時点(将来、公式ページが修正される可能性はあります)
A子
(ただし、古いバージョンであることには注意して…)
とりあえずデータベース名は「authdb」にして、usersテーブルの定義はさっきの公式ページの通りに作ってみよう
(単なるコピペだけど…)
|
create database authdb;
use authdb; CREATE TABLE users ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255), password VARCHAR(255), created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL ); |
あ、「role」という項目は削除したよ
んで、これを「authdb.sql」というファイル名で保存してっと…
C菜
そのファイル(authdb.sql)を「mysql」コマンドに渡しますね~
| mysql -u root -p < authdb.sql[Enter] |
もちろん「MATE端末」上で実行です~
B美
んじゃ、次は「CakePHP5」のプロジェクトを作成してね
A子
(超・適当(笑))
|
cd html[Enter]
composer create-project --prefer-dist cakephp/app authapp[Enter] |
もちろん、途中で止まったら「Y」を入力して[Enter]キーだね
↓
C菜
A子
(面倒だし…)
|
cd authapp[Enter]
bin/cake bake all users[Enter] |
で良いんだよね?
B美
先に「config」ディレクトリの中の「app.php」と「app_local.php」を修正しておきなさいね
でないと、bakeコマンドが通らない(エラーになる)わよ
A子
ん?何行目だったっけ?
C菜
A子
もはや慣れたもんだね
んじゃ、あらためて…
|
cd authapp[Enter]
bin/cake bake all users[Enter] |
↓
C菜
あ~、ただし…
データベーステーブルから「role」項目を(A子社長が勝手に)削除したので、それに関連するコードについては削りました~
|
public function validationDefault(Validator $validator): Validator
{ return $validator ->notEmpty('email', 'A email is required') ->email('email') ->notEmpty('password', 'A password is required'); } |
↓
A子
(さっき「src/Controller」ディレクトリの中にbakeコマンドで作ったけど…)
あれ?
特に書き換えるところは無さそうだよ
B美
(ここでは、いったんそのままにしておきましょう)
んじゃ、いよいよ「認証プラグイン」をインストールするわよ
| composer require "cakephp/authentication:^2.0"[Enter] |
ではなく
| composer require cakephp/authentication[Enter] |
だからね
C菜
えっと、次は「パスワードハッシュの追加」ですね~
「src/Model/Entity」の中にある「User.php」を修正するです~
まずは「$_accessible」フィールドを修正して~
|
protected array $_accessible = [
'*' => true, 'id' => false ]; |
あと「_setPassword」メソッドを追加します~
|
protected function _setPassword($password)
{ if (strlen($password) > 0) { return (new DefaultPasswordHasher)->hash($password); } } |
あ、先頭に次の一文を追加するのを忘れずに~
| use Cake\Auth\DefaultPasswordHasher; |
A子
えーっと
「src」ディレクトリの中にある「Application.php」を修正するんだね?
(基本的に公式サイトからのコピペだから、ソースコードは省略ね)
C菜
B美
| $this->loadComponent('RequestHandler'); |
の一文は挿入しないでね
(エラーになるから…)
A子
まぁ、気を取り直して…
次は「src/Controller」の中にある「UsersController.php」に三つのメソッドを追加すれば良いんだね
A子
ログイン後に表示されるページは「article」じゃなくて「top」にしたよ
なのでbakeコマンドで「TopController」を作ります
| bin/cake bake controller top[Enter] |
あと、「templates」の中に「Top」ディレクトリを作って、その中に「index.php」も作っておこう
(中身の無い空ファイルだけど…)
C菜
(ログインページです~)
A子
さて、うまく動くかな?
ブラウザのURL欄には「http://(IPアドレス)/authapp」を入れてっと…
(ドキドキ)
…って、あれ?
うまくいかない…
B美
リダイレクト先が「Webサーバのドキュメントルートを基点とした絶対パスになっている」から、うまくいかないのよ
もっとも簡単な解決策としては「/users/login」の箇所(二ヶ所あります)を「/authapp/users/login」に変更することなんだけど、もっとスマートな方法としては下記になるわね
(Routerクラスのurlメソッドを用いる方法)
|
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{ $authenticationService = new AuthenticationService([ 'unauthenticatedRedirect' => Router::url([ 'prefix' => false, 'plugin' => null, 'controller' => 'Users', 'action' => 'login', ]), 'queryParam' => 'redirect', ]); // 識別子をロードして、電子メールとパスワードのフィールドを確認します $authenticationService->loadIdentifier('Authentication.Password', [ 'fields' => [ 'username' => 'email', 'password' => 'password', ] ]); // 認証子をロードするには、最初にセッションを実行する必要があります $authenticationService->loadAuthenticator('Authentication.Session'); // メールとパスワードを選択するためのフォームデータチェックの設定 $authenticationService->loadAuthenticator('Authentication.Form', [ 'fields' => [ 'username' => 'email', 'password' => 'password', ], 'loginUrl' => Router::url([ 'prefix' => false, 'plugin' => null, 'controller' => 'Users', 'action' => 'login', ]), ]); return $authenticationService; } |
あ、先頭には以下の一文を必ず追加してね
| use Cake\Routing\Router; |
C菜
A子
ユーザを新規作成するために「Add User」をクリックしてみたんだけど、ユーザ登録のページが表示されない…
なんでだ?
B美
(自分でコードを打ち込んでおいて…)
「src/Controller」の「UsersController.php」の「beforeFilter」メソッドだけど…
| $this->Authentication->addUnauthenticatedActions(['login']); |
の箇所って、「login」だけは認証なしで表示できるって意味なのよ
(つまり、「login」以外は認証必須ってこと)
A子
てか、わかったよ
「add」メソッドをその配列要素に追加すれば良いんじゃない?
| $this->Authentication->addUnauthenticatedActions(['login', 'add']); |
ありゃ?
今度はこんなエラーが出たよ
B美
そこを「notEmptyString」に変更してね
|
public function validationDefault(Validator $validator): Validator
{ return $validator ->notEmptyString('email', 'A email is required') ->email('email') ->notEmptyString('password', 'A password is required'); } |
A子
公式ページがあてにならねぇ!(怒)
と、とにかく…
修正したら、ユーザ登録のページを表示することができたよ
C菜
あれ~?
またもやエラーになりましたよ~
B美
「_setPassword」メソッドについては、以下のように書き換えてほしいのよ
(先頭のuseの部分も一緒に…)
| use Authentication\PasswordHasher\DefaultPasswordHasher; |
|
protected function _setPassword($password)
{ if (strlen($password) > 0) { $hasher = new DefaultPasswordHasher(); return $hasher->hash($password); } } |
これもまた、公式があてにならない…ってパターンなんだけどね(苦笑)
A子
今度は(エラーが出ることなく)ユーザ登録できたよ
あ、さっきの
| $this->Authentication->addUnauthenticatedActions(['login', 'add']); |
だけど
| $this->Authentication->addUnauthenticatedActions(['login']); |
に戻しておいたほうが良いんだよね?
B美
一人でもユーザが存在すれば、そのユーザでログインすることで後は何人でもユーザを増やせるからね
ただし、セキュリティ面を考えると、「ユーザ管理ページにアクセスできるのは、BASIC認証を通った管理者のみ」にしておくほうが良いと思うわよ
さて、あとは公式ページと実際のコーディングについての差異をまとめておきましょうか
【総まとめ】
|
・composerでauthenticationをインストールする際、バージョンを指定しない
・$this->loadComponent('RequestHandler');は記述しない ・リダイレクト先のURLはRouterクラスを使って作成する ・ValidatorクラスのnotEmptyはnotEmptyStringに変更する ・DefaultPasswordHasherのパスは(Cake\Authではなく)Authentication\PasswordHasherとする |
C菜
A子
まぁ、うちにはB美がいるから大丈夫だけどね
C菜
あ、あとログインページをちょっと修正してみました~
(「Add User」のリンクは削除)
↓
A子
(「新規ユーザ登録」をこっちに移動させて、「ログアウト」のリンクも作ったよ)
↓
B美
ただ、Bulma(CSSフレームワーク)を組み込んだり、本格的に体裁を整えていくのは次回にしましょう
C菜
A子
単なるサンプルだから適当な名前(authapp)にしたんだけど、ここからこれをベースにしてなんか作っていくの?
B美
まぁ、なんにせよ見栄えは大事じゃん(笑)


