参考にさせて頂いたページ
Authコンポーネントについて
認証 — CakePHP Cookbook 2.x ドキュメント
シンプルな認証と承認のアプリケーション実装例について
シンプルな認証と承認のアプリケーション — CakePHP Cookbook 2.x ドキュメント
CakePHP で Session の保存先にデータベースを使用する方法について
CakePHP で Session の保存先にデータベースを使用する方法 | ウェブル
cakephpのセッションについて
セッション — CakePHP Cookbook 2.x ドキュメント
セッション保存用のテーブルを作成する
実行したsqlはセッション — CakePHP Cookbook 2.x ドキュメントにならって以下の通り。
CREATE TABLE `cake_sessions` ( `id` varchar(255) NOT NULL DEFAULT '', `data` text, `expires` int(11) DEFAULT NULL, PRIMARY KEY (`id`) );
Config/core.phpの編集
core.phpを見ると
Configure::write('Session', array( 'defaults' => 'php' ));
上記のように、初期設定がphpになっているので、
Configure::write('Session',array( 'defaults' => 'database', // Session情報をデータベースに保存する 'cookie' => 'SID', // cookieの配列のキー名この場合$_COOKIE['SID'] 'timeout' => 2160, // CakePHP のセッションハンドラがセッションを破棄するまでの時間で単位は分(36時間) // php.iniの設定内容を上書き 'ini' => Array( 'session.cookie_secure' => false, // httpとhttpsが混在しているサービスではfalse 'session.cookie_lifetime' => 129600, // ブラウザに送信するクッキーの有効期間で単位は秒(36時間) 'session.gc_maxlifetime' => 129600, // データが 'ごみ' とみなされ、消去されるまでの秒数(36時間) 'session.gc_divisor' => 100 // デフォルトは100 ) ));
とした。
Controller/AppController.phpを編集する
$componentsにAuthを渡したり、beforeFilterの処理内容を追加して、記述内容は以下の通り。
<?php /** * Application level Controller * * This file is application-wide controller file. You can put all * application-wide controller-related methods here. * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Controller * @since CakePHP(tm) v 0.2.9 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('Controller', 'Controller'); /** * Application Controller * * Add your application-wide methods in the class below, your controllers * will inherit them. * * @package app.Controller * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller */ class AppController extends Controller { public $components = array( 'DebugKit.Toolbar', 'Session', 'Auth' => array( // 認証が必要な画面を直接指定されたときのリダイレクト先 'loginAction' => array( 'controller' => 'users', 'action' => 'login', 'admin'=>true ), // ユーザのログインに使いたい認証オブジェクトの配列設定 'authenticate' => array( 'Form' => array( 'fields' => array( 'username' => 'email', // emailフィールドの値で認証 'password' => 'password' // passwordフィールドの値で認証 ), 'scope' => array( 'is_registered' => 1 // is_registeredフィールドの値も認証条件に追加 ), 'passwordHasher' => 'Blowfish' ) ), // ログイン直後に表示するページを指定 'loginRedirect' => array('controller' => 'users', 'action' => 'login'), // ログアウト直後に表示するページを指定 'logoutRedirect' => array('controller' => 'pages', 'action' => 'index'), // 未ログイン時のメッセージ 'authError' => 'メールアドレスまたはパスワードが違います。' ) ); //どのアクションが呼ばれてもはじめに実行される処理 public function beforeFilter() { // ログイン中のユーザー情報を取得 $user = $this->Auth->user(); $this->set('user',$user); // ログインしていないときでも許可されているアクション (allow()はすべてのアクションを許可) $this->Auth->allow(); } }
Controller/UsersController.phpを作成する
記述内容は以下の通り。
<?php App::uses('AppController', 'Controller'); class UsersController extends AppController { // Controller名 public $name = 'Users'; // 使用するModel public $uses = array('User'); public function login() { // 送信データが無いとき、またはpostアクセス以外の処理 if(!$this->request->data || !$this->request->is('post')){ $this->render(); return; } // 認証 if(!$this->Auth->login()){ // ログイン失敗時の処理 $this->Session->setFlash('ユーザー名またはパスワードが違います。'); return; } // 以下はログイン成功時の処理 $this->Session->setFlash(__('ログイン成功')); // ログイン中のユーザー情報を取得 $user = $this->Auth->user(); $this->set('user',$user); $this->redirect($this->Auth->redirectUrl()); } public function logout(){ $this->autoRender = false; $logout_url = $this->Auth->logout(); $this->redirect($logout_url); } }
View/Users/login.ctp
記述内容は以下の通り。
<h1>ログイン</h1> <br><br> <?php // ログイン判定 if(isset($user)){ echo('<p>現在ログイン中のユーザー情報は以下の通りです。</p>'); print_r($user); }else{ echo('現在ログインしていません。'); } ?> <br><br> <?php echo($this->Form->create('User')); ?> <div> <?php echo $this->Form->label('email', 'メールアドレス: '); echo $this->Form->text( 'email', array( 'errorMessage' => false, 'div' => false, 'required' => false ) ); ?> </div> <div> <?php echo $this->Form->label('password', 'パスワード: '); echo $this->Form->password( 'password', array( 'errorMessage' => false, 'div' => false, 'required' => false ) ); ?> </div> <?php echo($this->Form->end('ログイン')); ?>
今回学習できたこと
全てのアクションの前に実行させたい処理について
以下のように、AppControllerにbeforeFilterを記述することで、実行できる。
public function beforeFilter() { 〜処理内容〜 }
各Controllerに個別に処理を追加したい場合は、
public function beforeFilter() { parent::beforeFilter(); 〜当該のController〜で実行したい処理 }
のように記述する。
ログインしていないときに表示できるページを制限する
beforeFilter内で下記のように記述すると、ログインしていないときでも全てのアクションを許可する設定になる。
$this->Auth->allow();
beforeFilter内で下記のように記述すると、ログインしていないときに全てのアクションが許可されない設定になる。
$this->Auth->deny();
全てのアクションが許可されていない場合は下記のように$componentsに設定したアクションだけが表示される。
// 認証が必要な画面を直接指定されたときのリダイレクト先(ログインページ) 'loginAction' => array( 'controller' => 'users', 'action' => 'login' ),
だいたいはAppControllerのbeforeFilter内で$this->Auth->allow();
を書いて、denyしたい箇所だけ各Controllerに書いたら良さそうな感じがする。