CakePHP

CakePHP2.xで、Authコンポーネントを使って簡単認証する方法。

2019/12/10

CakePHP2.x(2.3.6)でAuthコンポーネントを使い、認証させる方法をポストします。
以前紹介した、CakePHP2.x及びDebugKitのインストールとともに初期状態をさくっと作るための忘備録です。

セッションの設定

ログイン関連にはセッションを使用するので、セッション関係の設定を行います。
app/Config/core.php の190行目付近変更します。

いくつか前のポストにもあるように単位が「秒」ではなく「分」って事に注意して設定します。
「セッションの保存先を、データベースにするよ」という設定です。
1440(分)は一日って意味です。

編集前

[php]
Configure::write('Session', array(
'defaults' => 'php'
));
[/php]

編集後

[php]
Configure::write('Session', array(
'defaults' => 'database',
'cookie' => 'SID',
'timeout' => 1440, // ←単位は分(60秒*24時間=1440分)
));
[/php]

テーブル作成

次に、セッションをデータベースに保存するって設定を行ったので、各種テーブルを作成します。

1.セッション保存用テーブル

[sql]
CREATE TABLE IF NOT EXISTS albeitshift_cake_sessions (
id varchar(255) NOT NULL DEFAULT '',
data text NOT NULL,
expires int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[/sql]

2.ユーザ用テーブル

次にユーザ用テーブル。
Authコンポーネントでは、『id』『username』『password』が最低限必要なカラムとなるので、それらを含んだテーブルを作成します。

[sql]
CREATE TABLE albeitshift_users (
id INT UNSIGNED AUTO_INCREMENT, -- ★必須
created DATETIME DEFAULT NULL, --
modified DATETIME DEFAULT NULL, --
username VARCHAR(255), -- ユーザ名★必須
password VARCHAR(255), -- パスワード★必須
role VARCHAR(255), -- ロール(役職)
email VARCHAR(255), -- メールアドレス
sort_order INT(11) default NULL, -- 並び順
is_deleted TINYINT NOT NULL default '0', -- 削除フラグ
publish TINYINT NOT NULL default '1', -- 公開フラグ
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[/sql]

コントローラー作成

では、コントローラーを作っていきます。
全部載せるのはちと面倒なので、重要なところだけ。

AppController

基底ファイルである AppController にコンポーネント設定を書き、全てのページに反映させます。
ハイライトされているところが、Authコンポーネント設定です。

beforeFilter() にある
[php]$this->set('userinfo', $this->Auth->user());[/php]
にて、ログイン中のユーザ情報を取得、セットするようにしています。

app/Controller/AppController.php

[php mark="14-34"]
class AppController extends Controller
{
// モデル
public $uses = array('User');

// ヘルパー
public $helpers = array('Html', 'Form', 'Js', 'Session');

// コンポーネント
public $components = array(
'Paginator',
'DebugKit.Toolbar', 'Session', 'String', 'ImageUpload',

// 以下、Authコンポーネント設定
'Auth' => array(
// ログインページのパス
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
'admin'=> true
),
// ログイン後のページを指定
'loginRedirect' => array(
'controller' => 'users',
'action' => 'list'
),
// ログアウト後の移動先
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
// 未ログイン時のメッセージ
'authError' => 'あなたのお名前とパスワードを入力して下さい。',
)
);

public function beforeFilter()
{
// ログイン中のユーザ情報をビューにセット
$this->set('userinfo', $this->Auth->user());

// 全ユーザ取得
$user_data = $this->User->find( 'list',
array(
'conditions' => null,
'fields' => array('User.username'),
'order' => null,
'recursive' => -1,
)
);
$this->set('user_data', $user_data);
}

// 以下略
}
[/php]

(2014.02.19追記)
下で説明している「Adminルーティング」を使用し、管理者用ログイン画面のURLを
[default]http://yourdomein.com/admin/users/login[/default]
としたい場合は、Appコントローラーのコンポーネント設定の「ログインページのパス」へ
[php]
'admin' => true
[/php]
を設定するとうまくいくようです。

更に追記です。
(1)削除済みのユーザに関してはログインさせたくない等の条件
(2)デフォルトではusername と passwordの判定だが、メールアドレスにて判定したい
の条件が必要になった場合は、下記の設定を追加すると幸せになれます。

[php]
// 条件追加
'authenticate' => array(
'Form' => array(
'scope' => array('User.is_deleted' => 0), // (1)is_deletedが立っていないユーザを対象とする
'fields' => array('User.username' => 'User.email'), // (2)認証をusernameからemailカラムに変更
)
),
[/php]

(追記ここまで)

UsersController

とりあえず、beforeFilter()、admin_login()、admin_logout()だけ。
"admin_"はプレフィックスを付けて管理画面とする、Adminルーティングてやつです。
詳しくは以前のポスト(CakePHP2.x で Admin Routing する方法。)を参照してください。

見ればわかると思いますが、特に目新しいことはしていません。

CakePHPの仕様で、AppControllerで beforeFilter() を指定している場合は、各コントローラーでも beforeFilter() が必要になるので、そのようにしています。

ログイン、ログアウトは非常に簡潔なルーチンで作成可能です。お手軽ですね。

略していますが、これ以外のアクションとしては(ごく普通に)ユーザの一覧、追加、修正、削除、インデックスページなどがあると思うので、それぞれ作成してください。

app/Controller/UsersController.php
[php]
class UsersController extends AppController
{
// モデル
var $uses = array('User');

/**
*
*/
public function beforeFilter()
{
// 親クラスのbeforeFilterの読み込み
parent::beforeFilter();

// 全ユーザ情報を取得
$user_data = $this->User->find( 'list',
array(
'conditions' => null,
'fields' => array('User.username'),
'order' => null,
'recursive' => -1,
)
);

// 認証不要のページの指定
if ( count($user_data) == 0 ) {
$this->Auth->allow('admin_login', 'admin_logout', 'admin_add');
} else {
// ユーザが1人以上なら、ユーザ追加アクションも権限を必要とさせる
$this->Auth->allow('admin_login', 'admin_logout');
}
}

/**
* ログイン
*
*/
public function admin_login()
{
// titleタグ
$this->set('title_for_layout', ログイン');

if ( $this->request->is('post') ) {
if ( $this->Auth->login() ) {
$this->redirect($this->Auth->redirect('/admin/users/index'));
} else {
$this->Session->setFlash(__('ユーザ名、メールアドレス、パスワードが不正です。'));
}
}
}

/**
* ログアウト
*
*/
public function admin_logout()
{
$this->redirect($this->Auth->logout());
}

// 以下略

}
[/php]

ビューの作成

と、あとは必要なビューとモデルを適当(適切)に作っていけば出来上がります。

新規ユーザ登録フォーム

このページは、ユーザが居ない初期状態の場合は認証なしで表示するよう、UsersController の beforeFilter() で設定しています。

app/View/Users/admin_add.ctp

[php]
echo $this->Form->create('User');

echo '

管理者名 : ';
echo $this->Form->input('username', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

echo '

メールアドレス : ';
echo $this->Form->input('email', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

echo '

パスワード : ';
echo $this->Form->input('password', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

echo '

ロール : ';
echo $this->Form->select('role', $mt_role, array('empty'=>false, 'value'=>'employee'));
echo '

';

// ボタン
echo $this->Form->end(__('登録実行'));
[/php]

ログインフォーム

app/View/Users/admin_login.ctp

[php]
echo $this->Form->create('User');

echo '

管理者名 : ';
echo $this->Form->input('username', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

echo '

メールアドレス : ';
echo $this->Form->input('email', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

echo '

パスワード : ';
echo $this->Form->input('password', array('size'=>30, 'label'=>false, 'error'=>false, 'div'=>false));
echo '

';

// ボタン
echo $this->Form->end(__('ログイン'));
[/php]

ログアウト後ページ

app/View/Users/admin_logout.ctp

[php]
echo '

ログアウトしました

';

echo '

    ';
    echo '

  • ' . $this->Html->link('ログインページへ','admin_login') . '
  • ';
    echo '

  • ' . $this->Html->link('新規作成','admin_add') . '
  • ';
    echo '

';
[/php]

indexページ

必要かどうかは分かりませんが、ログインしている人の情報を表示するページとします。

app/View/Users/admin_index.ctp

[php]
echo '

ようこそ!' . h($userinfo['username']) . 'さん

';
echo '

あなたの登録メールアドレスは' . h($userinfo['email']) . 'です。

';

echo '

管理者 INDEXページ

'."\n";

echo '

    ';
    echo '

  • ' . $this->Html->link('ログアウト', 'logout', array(), 'ログアウトしてもいいですか?') . '
  • ';
    echo '

  • ' . $this->Html->link('新規ユーザ作成', 'add', array()) . '
  • ';
    echo '

';
[/php]

モデルの作成

最後に、ユーザ登録時のバリデーションを行うモデルを作成します。

app/Model/User.php

[php]
'管理者',
"employee" => '社員',
"parttime" => 'アルバイト',
);

// バリデーション
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'ユーザ名は必須です。'
)
),

'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'メールアドレスは必須です。'
)
),

'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'パスワードは必須です。',
),
),

'role' => array(
'valid' => array(
'rule' => array('inList',
array(
'admin',
'employee',
'parttime',
)
),
'message' => 'ロール(役職)を選択して下さい。',
'allowEmpty' => false
)
)
);
}
[/php]

以上で、最低限ユーザ認証させるページが出来上がりました。
以下は、順を追ったスクリーンショットです。

スクリーンショット

1. 初期ユーザを登録

/admin/users/add で、初期ユーザを登録します。

AuthComponent画面1

2. ログイン画面

admin/users/login

AuthComponent画面2

3. ログイン後画面(INDEX)

ログイン後は、インデックスページヘリダイレクトするようにしたので、インデックスページを表示します。

AuthComponent画面3

ログアウト後は、ログインページが表示されるはずです。

と、かなり早足でしたが、Authコンポーネントを用いた、認証システムの作成方法でした。

[tgAmazonItemLookup asin="B00AXTVWEG" related="1"]

-CakePHP
-, ,