自動ログイン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); } }