綺麗に死ぬITエンジニア

CakePHP3.5以降で自動ログイン機能を簡単に実装できるプラグイン

2018-10-01

Laravelではフレームワーク内で実装されていて特にライブラリをインストールすることなく利用できる自動ログイン機能(Remember-Me認証)ですが、CakePHPでは標準で実装されていません。

かと言って、自動ログイン機能はセキュリティに大きく関わる部分なので、あまり独自実装はしたくないところ。

そこで、CakePHPで自動ログインを比較的簡単に導入できるプラグインを作成しました。

CakePHPはバージョン3.5以降でCookie周りの実装が大きく変更されました。巷で紹介されている自動ログイン機能は古いCookieの実装を利用していたり、また「これセキュリティやばいだろ…」と思うようなテキトーな実装だったりして、イマドキのちゃんとしたプラグインがなかったので自作しました。

オープンソースで公開してますので、セキュリティに懸念がある方はソースコード参照して問題がないことを確認してください。また、実装に何か問題があればissueやプルリクエストいただければと思います。

プラグインの紹介

今回作成した「RememberMe plugin for CakePHP」はGitHubで公開しています。

OSSで開発していますので、バグはもちろん、セキュリティに何かしら問題が判明した場合なども対応しますので、興味のある方は開発にご協力いただければと思います。

動作環境

このプラグインは以下の環境での動作をサポートしています。

  • CakePHP 3.5 以降
  • PHP 5.6 以降

インストール

1. プラグインの導入

まず、composerを使ってプラグイン本体を導入します。

composer require node-link/cakephp-remember-me

2. プラグインの読み込み

CakePHP3.6以降では次のようにしてプラグインを読み込みます。

<?php
// src/Application.php
use Cake\Http\BaseApplication;

class Application extends BaseApplication
{
    public function bootstrap()
    {
        parent::bootstrap();

        // Load the plugin
        $this->addPlugin('NodeLink/RememberMe');
    }
}

CakePHP3.5では次のようにしてプラグインを読み込みます。

// config/bootstrap.php

use Cake\Core\Plugin;

Plugin::load('NodeLink/RememberMe', ['bootstrap' => true]);

もしくは、以下のコマンドを実行して読み込みます(全てのバージョンで可能)。

bin/cake plugin load -b NodeLink/RememberMe

3. AuthComponentの設定

AppController.php内で、以下のようにAuthComponentの設定を行います。

<?php
namespace App\Controller;
use Cake\Controller\Controller;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Auth', [
            'authenticate' => [
                'Form' => [
                    'userModel' => 'Users',
                    'fields' => ['username' => 'username', 'password' => 'password'],
                ],
                'NodeLink/RememberMe.Cookie' => [
                    'userModel' => 'Users',  // 'Form'認証と同じモデルを指定します
                    'fields' => ['token' => 'remember_token'],  // Remember-Me認証用のトークンを保存するカラムを指定します
                ],
            ],
        ]);

        // ...
    }
}

4. データベースとモデルの更新

必要に応じて、データベースとモデルを更新します。

ALTER TABLE `users` ADD `remember_token` VARCHAR(64) NULL DEFAULT NULL;
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;

class User extends Entity
{
    protected $_hidden = [
        'password',
        'remember_token',  // 追加
    ];
}

5. ログイン画面の編集

以下のようにして、ログイン画面に自動ログイン用のチェックボックスを用意します。

<?= $this->Form->control('remember_me', ['type' => 'checkbox', 'label' => __('Remember me')]); ?>
Or
<?= $this->Form->checkbox('remember_me'); ?>
<?= $this->Form->label('remember_me', __('Remember me')); ?>

以上でインストールは終わりです。

何も設定せずとも、上記だけで一応動作しますので、ここで動作確認をしてください。

プラグインの設定値

config/.envconfig/app.phpを編集することで、プラグインの設定値を変更できます。

プラグインの設定値の初期値は以下のようになっています。

<?php
return [
    'Security' => [
        'cookieKey' => env('SECURITY_COOKIE_KEY', env('SECURITY_SALT', '__SALT__')),
    ],
    'RememberMe' => [
        'field' => 'remember_me',
        'cookie' => [
            'name' => 'remember_me',
            'expires' => '+1 year',
            'path' => '/',
            'domain' => '',
            'secure' => false,
            'httpOnly' => true,
        ],
    ],
];

セキュリティ上の観点から、config/.envSECURITY_COOKIE_KEYもしくはconfig/app.php'Security.cookieKey'に十分長いランダムな文字列を設定しておくことをお勧めします。

まとめ

以上で「RememberMe plugin for CakePHP」の紹介はおしまいです。

比較的簡単に自動ログイン機能が実装できますので、CakePHP 3.5 以降をお使いで実装にお悩みの方は是非利用してみてください。