これも今更ながら。毎度何かが抜けて慌てるのでポイントをメモ。
例によって、公式ドキュメントにちゃんと情報があることなので、そっち見たほうがいいとは思う!
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)で型変換して判定。