LoginSignup
18
26

More than 5 years have passed since last update.

CakePHP3で"ログイン状態の保持"を実装する

Posted at

cakephp3で "ログイン状態の保持" の機能を実装してみました。

※Quick Start Guide http://book.cakephp.org/3.0/en/quickstart.html に追加する感じで

方針

  • cookieとデータベースにログインキーを保持
  • 両者が一致したらログインとする

テーブル

auto_loginテーブルを作ります

CREATE TABLE `users` (
    `id` INT(11) AUTO_INCREMENT PRIMARY KEY,
    `email` VARCHAR(255) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `created` DATETIME,
    `modified` DATETIME
);

CREATE TABLE `auto_login` (
    `user_id` INT(11) UNSIGNED NOT NULL,
    `auto_login_key` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`user_id`)
);

view

チェックボックスを追加します

login.ctp
<h1>Login</h1>
<?= $this->Form->create() ?>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
<?= $this->Form->input('autologin', ['type' => 'checkbox']) ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

Controller

cookieを使うので、Cookieコンポーネントをloadします

AppController.php
$this->loadComponent('Cookie');

UserController.phpのlogin()とlogout()を修正します

UserController.php
    public function login()
    {
        if ($this->request->is('post')) {
            $user = $this->Auth->identify();
            if ($user) {
                if ($this->request->data('autologin') === '1') {
                    $this->__setupAutoLogin($user);
                }
                $this->Auth->setUser($user);
                $this->Flash->success(__('Log In Success.'));
                return $this->redirect($this->Auth->redirectUrl());
            }
            $this->Flash->error('Your username or password is incorrect.');
        } else {
            if ($autoLoginKey = $this->Cookie->read('AUTO_LOGIN')) {
                $this->loadModel('AutoLogin');
                $query = $this->AutoLogin->findByAutoLoginKey($autoLoginKey);
                if ($query->count() > 0) {
                    $userId = $query->first()->user_id;
                    $user = $this->Users->get($userId)->toArray();
                    if ($user) {
                        // 一度ログインキーを消してから再作成する
                        $this->__destroyAutoLogin($user);
                        $this->__setupAutoLogin($user);
                        $this->Auth->setUser($user);
                        $this->Flash->success(__('Auto Log In Success.'));
                        return $this->redirect($this->Auth->redirectUrl());
                    }
                }
            }
        }
    }

    public function logout()
    {
        $this->__destroyAutoLogin($this->Auth->user());
        $this->Flash->success('You are now logged out.');
        return $this->redirect($this->Auth->logout());
    }

ログインキーを保存するメソッドとログインキーを削除するメソッドを実装します

UserController.php
    private function __setupAutoLogin($user)
    {
        $this->loadModel('AutoLogin');
        $autoLoginKey = sha1(uniqid() . mt_rand(1, 999999999) . '_auto_login');
        $entity = $this->AutoLogin->newEntity([
            'user_id' => $user['id'],
            'auto_login_key' => $autoLoginKey
        ]);
        $this->AutoLogin->save($entity);

        $this->Cookie->config([
            'expires' => '+7 days',
            'path' => '/'
        ]);
        $this->Cookie->write('AUTO_LOGIN', $autoLoginKey);
    }

    private function __destroyAutoLogin($user)
    {
        $this->loadModel('AutoLogin');
        try {
            $entity = $this->AutoLogin->get($user['id']);
            if ($entity) {
                $this->AutoLogin->delete($entity);
                $this->Cookie->delete('AUTO_LOGIN');
            }
        } catch (RecordNotFoundException $e) {
            $this->Cookie->delete('AUTO_LOGIN');
        }
    }
18
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
26