自動ログイン2
今回は、ユーザー名とパスワードの代わりにユーザーを特定するキー(パスポートと呼びます)をクッキーとデータベースに記録します。ログインしていないユーザーがパスポートを持っていればデータベースからユーザーを特定し、自動でログインさせます。この例では、Authコンポーネントが使うセッションの有効期限とパスポートが使うクッキーの有効期限が異なります。
データベースにPassportsテーブルを作成します。
CREATE TABLE `passports` ( `id` int(11) NOT NULL auto_increment, `user_id` int(11) NOT NULL default '0', `passport` varchar(60) NOT NULL default '', `updated` datetime NULL , PRIMARY KEY (`id`) )
モデルを用意します。パスポートがユーザーに所属するようにアソシエーションを設定しておきます。
class Passport extends AppModel {
var $name = 'Passport';
var $belongsTo = array(
'User' =>
array('className' => 'User',
'foreignKey' => 'user_id',
));
}
Usersコントローラを修正します。有効期限を$expiresで設定します。
class UsersController extends AppController {
var $components = array('Auth','Cookie');
var $name = 'Users';
var $uses = array("Passport");//使用するモデルを追加
var $expires = "2 weeks";//パスポートの有効期限
function beforeFilter() {
$this->Auth->autoRedirect = false;
}
function login() {
$user=$this->Auth->user();//認証済みユーザを取得
if(!empty($this->data)){
//フォームからのデータの場合
if (empty($this->data['User']['remember_me'])) {
//パスポート不要なので削除
$this->__passportDelete($user);
} else {
//パスポート発行する
$this->__passportWrite($user);
}
unset($this->data['User']['remember_me']);
if ($user ) {
//ログインできた、リダイレクトする
$this->flash("ログインしました。",$this->Auth->redirect());
exit;
}
}
if ($user ) {
//認証できたユーザー。
$this->flash("ログインしています。",$this->Auth->redirect());
}else{
//認証でなかったユーザー。
$cookiePassport=$this->Cookie->Read('User');
if($cookiePassport){
//クッキーに記録したパスポートでログインしてみる
$deadline = date('Y-m-d H:i:s', strtotime("-".$this->expires));
// 比較演算子はキー側に(1.2betaからRCで仕様変更)
$options=array('conditions'=>array('Passport.passport'=>$cookiePassport['passport'],'Passport.updated >'=>" $deadline"));
$passport = $this->Passport->find("first",$options);
if($passport){
//該当するパスポートが見つかった
$user['username']=$passport['User']['username'];
$user['password']=$passport['User']['password'];
if($this->Auth->login($user)){
//ログインできたので、クッキーを更新してリダイレクトする
$this->__passportWrite($passport);
$this->flash("自動ログインしました。",$this->Auth->redirect());
}
}
}
}
// ログイン用フォームを表示する
}
function logout() {
$user=$this->Auth->user();
$this->__passportDelete($user);
$this->Session->setFlash('ログアウトしました');
$this->redirect($this->Auth->logout());//ログアウトし、ログイン画面へリダイレクト
}
function __passportDelete($user){
$this->Cookie->del('User');
$condition=array('Passport.user_id'=>$user['User']['id']);
$this->Passport->deleteAll($condition);
}
function __passportWrite($user){
$passport = array();
$passport['user_id']=$user['User']['id'];
$passport['passport']=Security::generateAuthKey();識別用にユニークなキーを生成
if(isset($user['Passport']['id']))$passport['id']=$user['Passport']['id'];
$this->Passport->save($passport);
$cookie = array('passport'=>$passport['passport']);
$this->Cookie->write('User', $cookie, true,"+ ".$this->expires);
}
}