【CakePHP】OpenIDをAuthComponentにトッピングしてみる
第3回CakePHP勉強会にて、LTした内容と関連するソースを公開します。
| View | Upload your own
AuthComponennt+OpenID
OpenIDに対応した会員制サイトを以下の組み合わせでさくっと作る
- PHP OpenID Library
- OpenID component for CakePHP
- AuthComponent
今回作成するアプリケーションの仕様
- 出来るだけコードを書かない方向で、動くものを作成
- modelはひとつ
- OpenIDで認証されたユーザは、Cakeアプリに自動ログイン
- OpenIDで認証されたユーザは、初回のみ、次の要領でCakeアプリに登録
usernameにidentity_url、
passwordに登録された時間をハッシュしたもの、
nicknameは画面から入力させる - OpenIDのユーザとして登録されたユーザを使って、Cakeアプリからはログインできない
- 入力チェック・セキュリティ対策などは、未実装
次から作業とコードです。
1.DB作成&Bake
(MySQLで行いました)
DB・tableを作成して、bakeでmodel、controller、view作成します。
今回は、usersのみ
CREATE TABLE `users` ( `id` int(10) NOT NULL auto_increment, `nickname` varchar(50) NOT NULL, `username` varchar(100) NOT NULL, `password` varchar(100) NOT NULL, `flag` int(1) NOT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
bakeでcontroller、viewにindex,view,add,deleteを作成
2.OpenID component for CakePHPの設置
http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/
からダウンロードして、 app/controllers/componentsに設置
同ページに書いてあるとおり、
app/views/users/login.ctp
と
app/controllers/users_controller.php
を作成。
3.PHP OpenID Libraryの設置
http://openidenabled.com/php-openid/
からダウンロード(2008/6/26現在バージョン 2.1.0)してvendorの下にAuthフォルダを配置
http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/ の指示に従って、修正
if ($key != ‘url’ && Auth_OpenID::arrayGet($q, $key) != $value) {
4.controllerの修正
2.で修正したapp/controllers/users_controller.php を修正(loginアクションに追加したのは42行目から)
class UsersController extends AppController {
var $name = 'Users';
var $helpers = array('Html', 'Form');
// var $components = array(,'Openid');
var $components = array('Auth','Openid');
function beforeFilter() {
$this->Auth->userScope = array('User.flag' => 0);
$this->Auth->loginAction = '/users/userlogin';
$this->Auth->logoutAction = '/users/userlogout';
$this->Auth->allow('add','login','openid_add','index','view');
}
function beforerender(){
$user = $this->Auth->user();
$this->set('auth', $user['User']['nickname']);
}
function login() {
$returnTo = ‘http://’.$_SERVER['SERVER_NAME'].’/users/login’;
if (!empty($this->data)) {
try {
$this->Openid->authenticate($this->data['OpenidUrl']['openid'], $returnTo, ‘http://’.$_SERVER['SERVER_NAME']);
} catch (InvalidArgumentException $e) {
$this->setMessage(’Invalid OpenID’);
} catch (Exception $e) {
$this->setMessage($e->getMessage());
}
} elseif (count($_GET) > 1) {
$response = $this->Openid->getResponse($returnTo);
if ($response->status == Auth_OpenID_CANCEL) {
$this->setMessage(’Verification cancelled’);
} elseif ($response->status == Auth_OpenID_FAILURE) {
$this->setMessage(’OpenID verification failed: ‘.$response->message);
} elseif ($response->status == Auth_OpenID_SUCCESS) {
$this->setMessage(’successfully authenticated!’);
// start controllerの修正
// echo ’successfully authenticated!’;
// exit;
$user = $this -> User -> find(’first’,array(
‘conditions’ => array(’User.username’ => $response->identity_url
,’User.flag’ =>1 )
,’recursive’ => -1 ));
if(!empty($user)){
//登録されているOpenIDユーザなら
$data = array(’User.username’ => $user['User']['username'],
‘User.password’ => $user['User']['password'] );
$this -> __autologinForOpenid($data);
}else{
//登録されているOpenIDユーザならニックネーム登録
$this -> Session -> write(’identity_url’, $response -> identity_url);
$this -> redirect( ‘/users/openid_add’ );
}
}
}
}
function openid_add(){
if(!empty($this -> data)){
if ($this->Session->check(’identity_url’)) {
$identity_url = $this->Session->read(’identity_url’);
}else{
exit;
}
$data=$this->data;
$this -> User -> create();
$savedata =array(’username’ => $identity_url ,
‘password’ => $this->Auth->password( time()),
‘nickname’ => $data['User']['nickname'] ,
‘flag’ => 1);
$this->User->set($savedata);
$validates=$this->User->validates();
if($this->User->validates()) {
$this->User->save();
$this->Session->delete(’identity_url’);
$this->Session->setFlash(’ニックネームの登録が終了しました。’);
$data = array(’User.username’ => $savedata['username'],
‘User.password’ => $savedata['password'] );
$this -> __autologinForOpenid($data);
}
}
}
function userlogin(){
}
function userlogout(){
$this->Session->setFlash(’ログアウトしました’);
$this->Auth->logout();
$this->redirect(’/users/index’);
}
function __autologinForOpenid($user){
$this -> Auth -> userScope = array( ‘User.flag’ => 1 );
$this -> Auth -> login($user);
$this -> redirect( ‘/users/index’ );
}
private function setMessage($message) {
$this->set(’message’, $message);
}
//end controllerの修正
bakeで作られたindex,view,add,deleteは略
viewの追加
Cakeアプリのログイン画面
app/views/users/userlogin.ctp
<?php
if ($session->check('Message.auth')) $session->flash('auth');
echo $form->create('User', array('action' => 'userlogin'));
echo $form->input('username');
echo $form->input('password');
echo $form->end('Login');
?>
OpenID認証されたユーザで、Cakeアプリ未登録ユーザの場合、ニックネームを入力させる画面
app/views/users/openid_add.ctp
<?php
echo $form->create('User', array('action' => 'openid_add'));
echo $form->input('nickname');
echo $form->submit();
echo $form->end();
?>
Windowsな人向け
OSをwindowsを使っている人は、
Define Auth_OpenID_RAND_SOURCE as null to continue with an insecure random number generator.
と乱数ジェネレータがないと怒られるので、app/controllers/components/openid.phpに追加すると、PHPの乱数ジェネレータを使います。
if (!strncmp(PHP_OS, 'WIN', 3)) {
define('Auth_OpenID_RAND_SOURCE', NULL);
}
AuthComponentの使い方
AuthComponentには、$this->Auth->loginActionで指定したアクション以外からログインさせる手段が、最初から用意されています。
$this -> Auth -> login($data)
使い方は至って簡単です。ユーザ名とハッシュ化されたパスワードを渡すだけです。
$data = array(
'User.username' => $user['User']['username'],
‘User.password’ => $user['User']['password'] );
$this -> Auth -> login($data);
それ以外の部分は、以下にまとめていますので、ごらんください。
【CakePHP】AuthComponentについてのまとめ 【ざっくり基本編】 【CakePHP】AuthComponentについてのまとめ その2【ちょっとしたコツ編】
【CakePHP】AuthComponentについてのまとめ その3【ログイン後のリダイレクト編】
Popularity: 19 %
by 赤がすき 





(2 投票, 平均: 4.5 中 5)



コメントはまだありません。