CakePHP3に認証機能を追加する

CakePHP3ではユーザー認証機能(ログイン機能)が簡単に実装できます。本記事はユーザー認証機能の追加手順です。
あらかじめデータベースにusersテーブルを作成しておきます。

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/をブラウザで開き、以下の画面が表示されることを確認します。

CakePHP3認証画面の追加

ユーザー追加画面の追加

ログインユーザーを追加する画面を追加します。

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すればユーザーを追加できます。

CakePHP3ユーザー追加画面

認証機能の実装

Controller の変更

  • src\Controller\UsersController.phpbeforeFilter()を変更します
  • 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にアクセスします。
ログインしていなくても以下の画面が表示されます。

CakePHP3認証画面の追加

http://ホスト名/{CakePHPプロジェクト}/members/topにアクセスします。
ログインしていないとログイン画面に遷移します。

CakePHP3認証画面の追加

ログインすると画面が表示されます。

CakePHP3認証画面の追加

ログアウト処理

コントローラでのログアウト

ログアウトページへリダイレクトすることでログアウトを行います。

$this->redirect($this->Auth->logout());

ビューでのログアウトリンク作成

/users/logoutにアクセスするだけでログアウトします。

<a href="<?= $this->Url->build("/users/logout", true); ?>">ログアウト</a>
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です