これも今更ながら。毎度何かが抜けて慌てるのでポイントをメモ。
例によって、公式ドキュメントにちゃんと情報があることなので、そっち見たほうがいいとは思う!
http://book.cakephp.org/2.0/ja/core-libraries/components/authentication.html
AppControllerのcomponentsにAuthを追加。
あといい感じにカスタマイズ部分はパラメータ追加。
var $components = array(
'Session',
'Cookie',
'Auth' => array(
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'top', 'action' => 'index'),
'authenticate' => array('Form' => array('userModel' => 'User', 'fields' => Array('username' => 'email')))
)
);
対象のModelのbeforeSaveでパスワードの暗号化
public function beforeSave($options = array()) {
// make a password for digest auth.
$this->data['User']['digest_hash'] = DigestAuthenticate::password(
$this->data['User']['username'], $this->data['User']['password'], env('SERVER_NAME')
);
return true;
}
これやらないとパスワードが平文で保存されてしまい、ログインもできぬ。
Viewはログインとユーザー登録ページを追加。
signup.ctp
<div>
<?php echo $this->Form->create('User', array('class' => 'form-horizontal'));?>
<fieldset>
<legend>ユーザー登録</legend>
<?php
echo $this->Form->input('email', array('label' => 'メールアドレス', 'required' => 'required'));
echo $this->Form->input('password', array('label' => 'パスワード', 'required' => 'required'));
?>
<?php echo $this->Form->submit('登録');?>
</fieldset>
<?php echo $this->Form->end();?>
</div>
login.ctp
<div>
<?php echo $this->Form->create('User', array('class' => 'form-horizontal'));?>
<fieldset>
<legend>ログイン</legend>
<?php
echo $this->Form->input('email', array( 'label' => 'メールアドレス', 'required' => 'required'));
echo $this->Form->input('password', array( 'label' => 'パスワード', 'required' => 'required'));
echo $this->Form->submit('ログイン');
?>
</fieldset>
<?php echo $this->Form->end(); ?>
</div>
Users Controllerにこいつらとログアウト処理を追加。
public function signup() {
if ($this->request->is('post')) {
// 必要があればデータ調整
$this->request->data['User']['flg'] = 1;
// 保存
$this->User->create();
if ($this->User->save($this->request->data)) {
// そのままログイン処理してしまう。
$id = $this->User->id;
$this->request->data['User'] = array_merge($this->request->data['User'], array('id' => $id));
$this->Auth->login($this->request->data['User']);
// リダイレクト
$this->Session->setFlash('ユーザー登録OK');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('エラーや!');
}
}
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->Session->setFlash('ログインできたで!');
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash('エラーやで!');
}
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
あとは各Controllerで、認証不要のページは許してあげておく。
public function beforeFilter() {
$this->Auth->allow('*'); // このController全て認証不要
// $this->Auth->allow('view', 'index'); // viewとindexは認証不要
parent::beforeFilter();
}
あと、個人的によくやるのはAppControllerのbeforeFilterで、ログイン状態の確認と共通ヘッダーとかで使うデータの取得。
public $is_login = false;
public $uid = 0;
public $username = "ゲスト";
public function beforeFilter() {
$this->is_login = (bool)$this->Auth->user();
if ($this->is_login) {
$this->uid = $this->Auth->user('id');
$this->username = $this->Auth->user('username');
}
$this->set('is_login', $this->is_login);
$this->set('uid', $this->uid);
$this->set('username', $this->username);
parent::beforeFilter();
}
こんなもんかな?他にあったらまた追記しよう。
追記)redirect()は2.3までだった。以降はredirectUrl()。
追記)loggedIn()も2.4までだった。以降はuser()を(bool)で型変換して判定。