CakePHP3に認証機能を追加する
CakePHP3ではユーザー認証機能(ログイン機能)が簡単に実装できます。本記事はユーザー認証機能の追加手順です。
あらかじめデータベースにusers
テーブルを作成しておきます。
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created DATETIME DEFAULT NULL DEFAULT CURRENT_TIMESTAMP,
modified DATETIME DEFAULT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
認証画面のベース作成
まずは認証用のコントローラーを用意します。
Table の作成
src\Model\Table\UsersTable.php
を作成します。
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('username', 'このフィールドに入力してください。')
->add('password', [
'length' => [
'rule' => ['minLength', 8],
'message' => 'パスワードは 8 文字以上必要です。'
]
]);
}
}
Entity の作成
パスワードのハッシュ化を行うため、User
というEntity
クラスを作成します。
src\Model\Entity\User.php
を作成します。
<?php
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;
class User extends Entity
{
// 主キーフィールド "id" を除く、すべてのフィールドを一括代入可能にします。
protected $_accessible = [
'*' => true,
'id' => false
];
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}
}
Controller の作成
src\Controller\UsersController.php
を作成します。
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
}
public function index()
{
$this->set('users', $this->Users->find('all'));
}
}
ビューの実装
src\Template\Users\index.ctp
を作成します。
<h1>users</h1>
<table>
<tr>
<th>id</th>
<th>username</th>
</tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user->id ?></td>
<td><?= $this->Html->link($user->username, ['action' => 'view', $user->id]) ?></td>
</tr>
<?php endforeach; ?>
</table>
ここまでで、http://ホスト名/{CakePHPプロジェクト}/users/をブラウザで開き、以下の画面が表示されることを確認します。
ユーザー追加画面の追加
ログインユーザーを追加する画面を追加します。
Controllerの変更
src\Controller\UsersController.php
にユーザー追加画面(addUser()
)を追加します。
class UsersController extends AppController
{
public function addUser()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'addUser']);
}
$this->Flash->error(__('Unable to add the user.'));
}
$this->set('user', $user);
}
}
ビューの実装
src\Template\Users\add_user.ctp
を作成します。
<div class="users form">
<?= $this->Form->create($user) ?>
<fieldset>
<legend><?= __('Add User') ?></legend>
<?= $this->Form->control('username') ?>
<?= $this->Form->control('password') ?>
</fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>
</div>
http://ホスト名/{CakePHPプロジェクト}/users/add-userをブラウザで開くと、以下の画面が表示されます。
UsernameとPasswordを入力してSUBMITすればユーザーを追加できます。
認証機能の実装
Controller の変更
src\Controller\UsersController.php
のbeforeFilter()
を変更しますlogin()
を追加しますlogout()
を追加します
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['addUser', 'logout']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
//$this->request->session()->delete('Auth.redirect'); // 固定ページに移動させたい場合
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
}
src\Controller\AppController.php
を以下のように変更します。(以下を追加の部分)
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler', [
'enableBeforeRedirect' => false,
]);
$this->loadComponent('Flash');
// 以下を追加.
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'loginRedirect' => [
'controller' => 'Members',
'action' => 'top'
],
'logoutRedirect' => [
'controller' => 'Members',
'action' => 'index'
]
]);
}
// 以下を追加.
public function beforeFilter(Event $event)
{
$this->Auth->allow(['index']);
}
キー | 内容 |
---|---|
loginAction |
ログイン処理をどのプログラムで行うかをで定義する |
loginRedirect |
ログイン後にどのページに遷移するかを定義する |
logoutRedirect |
ログアウト後にどのページに遷移するかを定義する |
Auth->allow()
認証無しでも見れるページを指定します。
ビューの実装
ログイン用のフォーム画面を実装します。
src\Template\Users\login.ctp
を作成します。
<div class="users form">
<?= $this->Flash->render() ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your username and password') ?></legend>
<?= $this->Form->control('username') ?>
<?= $this->Form->control('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
認証処理の確認
src\Controller\MembersController.php
を追加します。
<?php
namespace App\Controller;
class MembersController extends AppController
{
// 認証なしでも見れる.
public function index()
{
}
// 認証しないと見れない.
public function top()
{
}
}
各画面のビューを実装します。
src\Template\Members\top.ctp
を作成します。
<h1>ログインしないと見れません</h1>
src\Template\Members\index.ctp
を作成します。
<h1>ログインなしでも見れます</h1>
http://ホスト名/{CakePHPプロジェクト}/membersにアクセスします。
ログインしていなくても以下の画面が表示されます。
http://ホスト名/{CakePHPプロジェクト}/members/topにアクセスします。
ログインしていないとログイン画面に遷移します。
ログインすると画面が表示されます。
ログアウト処理
コントローラでのログアウト
ログアウトページへリダイレクトすることでログアウトを行います。
$this->redirect($this->Auth->logout());
ビューでのログアウトリンク作成
/users/logout
にアクセスするだけでログアウトします。
<a href="<?= $this->Url->build("/users/logout", true); ?>">ログアウト</a>