
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 '
- ';
- ' . $this->Html->link('ログインページへ','admin_login') . '
- ' . $this->Html->link('新規作成','admin_add') . '
echo '
';
echo '
';
echo '
';
[/php]
indexページ
必要かどうかは分かりませんが、ログインしている人の情報を表示するページとします。
app/View/Users/admin_index.ctp
[php]
echo '
ようこそ!' . h($userinfo['username']) . 'さん
';
echo '
あなたの登録メールアドレスは' . h($userinfo['email']) . 'です。
';
echo '
管理者 INDEXページ
'."\n";
echo '
- ';
- ' . $this->Html->link('ログアウト', 'logout', array(), 'ログアウトしてもいいですか?') . '
- ' . $this->Html->link('新規ユーザ作成', 'add', array()) . '
echo '
';
echo '
';
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 で、初期ユーザを登録します。
2. ログイン画面
admin/users/login
3. ログイン後画面(INDEX)
ログイン後は、インデックスページヘリダイレクトするようにしたので、インデックスページを表示します。
ログアウト後は、ログインページが表示されるはずです。
と、かなり早足でしたが、Authコンポーネントを用いた、認証システムの作成方法でした。
[tgAmazonItemLookup asin="B00AXTVWEG" related="1"]