CakePHP::obAuthを使ったユーザ認証
7月 2nd, 2007 admin Posted in CakePHP, PHP | 7 Comments »
アクセス有難う御座います。当ページのobAuthを使った認証はCakePHP1.1用のものです。
CakePHP1.2以降では標準の認証コンポーネントを使うことが推奨されており、そちらの方がずっと簡単になっています。
詳しくはCakePHPのマニュアルページをご覧下さい。
http://book.cakephp.org/ja/view/172/Authentication
obAuth Simple Authenticationを使ったユーザ認証を作成しました。
以下の内容はobAuth Component Tutorialの内容のエスパー翻訳+作業ログになっています。
イントロダクション
obAuthはシンプルな認証用のコンポーネントです。下記のような感じで超簡単に権限設定が行えます。
< ?php $this->obAuth->lock(array(1)); ?>
この場合ユーザグループが1のユーザだけがこのアクションを実行できるということになります。簡単でしょう?
なお、このコンポーネントはまだアルファな段階なのでフィードバックとかよろしく!
目次
- コンポーネントのダウンロード
- データベーステーブルの作成
- コンポーネントの設置とモデルの作成
- 必要なアクションの設定
- 認証の開始
- そのほかTips&Tricks
コンポーネントのダウンロード
コンポーネントをhttp://bakery.cakephp.org/articles/view/130からダウンロードしてください。
お勧めのデータベーステーブル
obAuthではusersとgroupsというテーブルを使用します。
Download code
usersテーブルはid, group_id, username, passwordのカラムさえあればなんでもOKです。
-- -------------------------------------------------------- -- -- Table structure for table `groups` -- CREATE TABLE `groups` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', `created` datetime NOT NULL default '0000-00-00 00:00:00', `modified` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT; -- -- Dumping data for table `groups` -- INSERT INTO `groups` (`id`, `name`, `created`, `modified`) VALUES (1, 'Member', '0000-00-00 00:00:00', '0000-00-00 00:00:00'); INSERT INTO `groups` (`id`, `name`, `created`, `modified`) VALUES (2, 'Admin', '0000-00-00 00:00:00', '0000-00-00 00:00:00'); -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE `users` ( `id` int(10) unsigned NOT NULL auto_increment, `username` varchar(50) NOT NULL default '', `password` varchar(32) NOT NULL default '', `fname` varchar(50) NOT NULL, `lname` varchar(50) NOT NULL, `email` varchar(100) NOT NULL default '', `group_id` int(10) unsigned NOT NULL default '0', `active` tinyint(1) unsigned NOT NULL default '0', `created` datetime NOT NULL default '0000-00-00 00:00:00', `modified` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`), KEY `group_id` (`group_id`) ) ENGINE=InnoDB DEFAULT;
コンポーネントの設置とモデルの作成
コンポーネントをダウンロードしたら/app/controllers/components/ob_auth.phpって感じで設置してください。
そして、設置が終わったらコントローラーからコンポーネントを呼んでください。この例ではposts_controller.phpを使います。
< ?php
class PostsController extends AppController
{
var $name = 'Posts';
var $components = array("obAuth"); //この行で呼んでいる
}
?>
次は、UserモデルとGroupモデルのアソシエーションを設定しよう。もしわかってないならhttp://wiki.cakephp.org/docs:understanding_associations
を見るように。(日本語だとhttp://cakephp.jp/doc/ch06s04.html)
2007/07/10追記
/app/models/group.php
class Group extends AppModel {
var $name = 'Group';
var $hasMany = array('User' => array(
'className' => 'User'
)
);
}
/app/models/user.php
class User extends AppModel {
var $name = 'User';
var $belongsTo = array(
'Group' =>
array('className' => 'Group',
'foreignKey' => 'group_id',
'conditions' => '',
'fields' => '',
'order' => '',
'counterCache' => ''
),
);
}
これが終わったら、ついにobAuthが使えるよ!
必要なアクションの設定
obAuth componentを使うには重要なLogin、Logoutアクションが必要だ。
/app/controllers/users_controller.phpを作りましょう
< ?php
class UsersController extends AppController
{
var $name = "Users";
var $components = array("obAuth");
function login()
{
if(isset($this->data['User']))
{
if($this->obAuth->login($this->data['User']))
{
$this->redirect('/users');
}
$this->flash("Username/Password is incorrect","/users/login");
}
}
function logout()
{
$this->obAuth->lock();
$this->obAuth->logout();
$this->flash('You are now logged out.');
$this->redirect('/');
}
}
?>
次は、ビューだ。ログアウトはリダイレクトするだけだからログインのやつだけでOK
<?php echo $html->formTag('/users/login')?>
<fieldset>
<legend>User Login</legend>
<label for="username">Username: </label>
<?php echo $html->input('User/username', array('style' => 'width: 150px'))?><br />
<label for="password">Password: </label>
<?php echo $html->password('User/password', array('style' => 'width: 150px'))?><br />
<label for="submit"> </label><br />
<?php echo $html->submit('Sign In')?>
</fieldset>
</form>
認証の開始
PostsコントローラのaddアクションでグループIDが3の人だけ実行できるような認証にするときはこんな感じ
< ?php
function add()
{
$this->obAuth->lock(array(3)); // Only users with the group_id '3' are allowed here
if (!empty($this->data))
{
if ($this->Post->save($this->data))
{
$this->flash('Your post has been saved.','/posts');
}
}
}
?>
んで、もしグループIDが2と3の人に許可したいなら
$this->obAuth->lock(array(2,3));
こんな感じに書けます。
グループIDを空にしたときにはすべてのユーザに許可したことになります。
追記
obAuthのチュートリアルにbeforeFilterでの認証方法が書かれていました。
function beforeFilter(){
$this->obAuth->startup($this);
if($this->params['action'] != 'login'){
$this->obAuth->lock(array(1,2,3));
}
}
ビューでの扱い方
CakePHPではビューにコンポーネントは自動的にセットされているようなので
< ?php if(isset($obAuth->User)){ ?>
<li>< ?php echo $html->link("ログアウト","/users/logout"); ?></li>
< ?php } ?>
こんな感じでかける。超簡単です。
要変更
ob_auth.phpの中で$sesskeyが定義されているけど、これは自分用のランダムな値に書き換えておくべきなんだと思う。
追記:2007/07/07
コントローラーで$this->obAuth->login($this->data);とかした直後にgetGroupID()とかが使えなかったので、コンポーネントのログイン処理の最後のところでuserをセットするように変更した。
obAuth#login()
// Method to check if user is logged.
function login($data)
{
$username = $data["{$this->user_fields['username']}"];
$password = $data[$this->user_fields['password']];
$conditions = array($this->user_model.".".$this->user_fields['username'] => $username, $this->user_model.".".$this->user_fields['password'] => md5($password), $this->user_model.".active" => 1);
$user = $this->controller->{$this->user_model}->find($conditions);
if (empty($user)) {
return false;
} else {
$sessdata["{$this->user_model}"]['id'] = $user["{$this->user_model}"]["{$this->user_fields['id']}"];
$sessdata["{$this->user_model}"]['username'] = $user["{$this->user_model}"]["{$this->user_fields['username']}"];
$sessdata["{$this->user_model}"]['password'] = $user["{$this->user_model}"]["{$this->user_fields['password']}"];
$sessdata["{$this->group_model}"]['id'] = $user["{$this->group_model}"]["{$this->group_fields['id']}"];
$sessdata["{$this->group_model}"]['name'] = $user["{$this->group_model}"]["{$this->group_fields['name']}"];
$sessdata["{$this->user_model}"]['login_hash'] = md5($this->sesskey . $sessdata["{$this->user_model}"]['username'] . $sessdata["{$this->user_model}"]['password'] . $sessdata["{$this->group_model}"]['id']);
$this->Session->write($this->sesskey, $sessdata);
$this->user = $this->Session->read($this->sesskey);
return true;
}
}
2007/07/09追記
snapz CakePHP いちばん簡単な認証システムで指摘を受けたので、SQLのコードを記事内に掲載しました。後半の解説が分からないとのことですが・・・ぜひコメント、トラックバックください。
7月 9th, 2007 at 17:13:11
素早い対応に驚きました。感謝感激
解説がわからない なんて書き方は失礼でした。すいません。
修正しました。
3月 19th, 2008 at 16:25:05
このままだと、
http://domain.com/blog/delete/3
とすると削除しちゃうようですね。
3月 19th, 2008 at 16:25:22
このままだと、ログインしなくても
http://domain.com/blog/delete/3
とすると削除しちゃうようですね。
7月 31st, 2008 at 17:13:30
XAMPP(PHP5.2.4)で動いていた obAuth ですが
FreeBSD6.3(PHP5.2.6)で動かしたときに,
Notice (8): Trying to get property of non-object [APP/controllers/components/ob_auth.php, line 41]
というエラーに悩まされました.
現象としては,login()メソッドの
$user = $this->controller->{$this->user_model}->find($conditions);
の部分で,$this->controller がなくなっていました.
困りつつも,いろいろ試行錯誤した結果,php.ini の
zend.ze1_compatibility_mode = On
をOffにしたら,startup()で渡したcontrollerをちゃんと保持
できるようになり,うまく動作しました.
やっぱり,ちゃんと理解しないで使うと嵌りますね...
11月 10th, 2009 at 19:57:27
[...] http://www.jamboree.jp/cms/archives/10 コメントをどうぞ 返信をキャンセル [...]
1月 28th, 2011 at 10:33:14
yo
2月 18th, 2011 at 1:15:45
I unquestionably agree with everything you have said. In fact, I browsed throughout your additional blogposts and I’m sure you are completely correct. Best wishes with this particular blog.