【CakePHP】AuthComponentについてのまとめ その2【ちょっとしたコツ編】
【CakePHP】AuthComponentについてのまとめ 【ざっくり基本編】 の続きです。
CakePHPの1.2.0.6311-betaでの話。
暗号化のタイミングとvalidation
※stable版では、Auth->allow()に指定すれば、Model内のvalidationを使えるようになりそうです(2008/3/17更新)
Auth->allow()に含まれるアクションの場合はパスワードがハッシュ化されなくなるようです。これでモデル内のvalidationを適用できますね。
不明。RC版では、方針が元にもどった模様
2008.8.11 custarさんよりコメントで「ログインしているかどうか、チェック仕方は?」について、誤りがあることを教えて頂き、その部分を修正致しました。
前回のソースをみるとControllerの処理に暗号化の処理がないことに気付きます。
//ログイン
function login(){
}
//ユーザ追加
function add() {
if (!empty($this->data)) {
$this->User->create();
$this->User->save($this->data['User']);
$this->redirect(array(’action’ => ‘index’));
}
つまり、AuthComponentが暗号化の処理も自動的にやってくれます。
なのですが、ちょっと注意が必要です。
例えば、「パスワードは英数字4文字以上8文字以内」なんていう制限をかけたい場合、
CakePHP の1.2から実装された、Model内の強力なvalidationを使いたいところですが、
modelやcontrollerに制御が戻ってきた時点ですでに暗号化されています。
従って、
class User extends AppModel {
var $name = 'User';
var $validate = array(
'password' => array(
'rule1' => array('rule' => array('between' , 4 , 8)),
'rule2' => array('rule' => array('alphaNumeric'))
)
);
}
という風に書いてもチェックできません(ハッシュ化された後のデータでvalidationされるから)。
「ユーザ登録時に再入力パスワードと一致しているかチェックしたい 」場合も同様です
簡単な方法としては、
modelと違う名前で受けて、controller側でエラー処理を行う方法が考えられます。
ユーザ追加用のview(view/users/add.ctp)
<?php
echo $form->create('User', array('action' => 'add'));
echo $form->input('username');
//UserではなくParamという名前でフォームからデータを受けとる
echo $form->input('Param/password');
echo $form->submit();
echo $form->end();
echo $form->error('Param::password_len','パスワードは4~8文字の範囲で入力して下さい。');
echo $form->error('Param::password','パスワードは半角の英数字で入力して下さい。');
?>
ユーザ追加用のcontroller(controllers/users_controller.ctp)
2008.10.21 Kさんよりコメントで閉じかっこが不足していることを教えて頂き、修正しました。
//ユーザ追加
function add()
{
if (!empty($this->data))
{
$this->User->create();
if(!ctype_alnum($this -> data['Param']['password']))
{
$this->User->invalidate(’Param::password’);
}else{
if(strlen($data['Param']['password'])<4 || strlen($data['Param']['password'])>8)
{
$this->User->invalidate(’Param::password_len’);
}
$this->User->data=$data;
$this->User->validates();
if(count($this->User->validationErrors)>0)
{
//パスワードを暗号化して、model Userに渡す
$data['User']['password']=$this->Auth->password( $data['Param']['password'] );
$this->User->save($this->data['User']);
$this->redirect(array(’action’ => ‘index’));
}
}
}
}
※上記のように暗号化を自分で行いたい場合は次のように書きます
$hash=$this->Auth->password( $password] );
デフォルトから変更する場合
AuthComponentは、以下のように色々カスタマイズが可能です。
$this->Auth->allowのみ、各controllerに書いて、共通のものをapp_controllerに指定するのが楽かもしれません
app_controllerの例
function beforeFilter()
{
//ログインできるユーザの条件をデータベースのフィールドの値で指定
$this->Auth->userScope = array('User.verified' => 1);
//ログイン処理を行うactionを指定(/users/loginがデフォルト)。
$this->Auth->loginAction = '/users/userlogin';
//ログインが失敗した際のエラーメッセージ
$this->Auth->loginError = 'ログインエラーです';
//権限が無いactionを実行した際のエラーメッセージ
$this->Auth->authError = '権限がありません';
//ログイン後にリダイレクトするURL
$this->Auth->loginRedirect = '/users/myhome';
//ユーザIDとパスワードがあるmodelを指定('User'がデフォルト)
$this->Auth->userModel = 'Name';
//ユーザIDとパスワードのフィールドを指定(username、password がデフォルト)
$this->Auth->fields = array('username' => 'email', 'password' => 'pwd');
}
各controllerの例
function beforeFilter()
{
parent::beforeFilter();
//ログインを必要としない処理 指定しないと全てのactionでログインが必要となるので注意
$this->Auth->allow('view','add');
}
ログインに失敗した際のメッセージは、どうやって処理するの?
AuthComponentのエラーメッセージ処理ですが、エラーが起きるとsetFlashを使って、メッセージをセッションにkey’auth’に書き込んでくれます。
従ってログインフォームに、次のように書くとエラーメッセージが取り出せます
< ?php if ( $session->check('Message.auth') )
{
$session->flash('auth');
}
?>
ログインしているかどうか、チェック仕方は?
2008.8.11 custarさんよりコメントで誤りがあることを教えて頂きました。
2008.10.15 nishiさんよりコメントで誤りがあることを教えて頂きました。
次のように書くと取得できます
$this->Auth->isAuthorized()
$user = $this->Auth->user();
if ($user)
{
//logged in
}else{
// not logged in
}
現在ログインしているユーザ名やIDの取り出し方
$user=$this->Auth->user();
とすると、ユーザ情報が保管されているmodelが取得できます。後は何なりと好きにして状態。もちろん、フィールド単位でも可能です
$userid=$this->Auth->user('id');
まとめ
※おかしなところがありましたら、ご指摘頂けると幸いです。
【CakePHP】AuthComponentについてのまとめ 【ざっくり基本編】
【CakePHP】AuthComponentについてのまとめ その2【ちょっとしたコツ編】
【CakePHP】OpenIDをAuthComponentにトッピングしてみる
とあわせて読んでいただけると、理解が深まります。
参考にさせて頂いたサイト
http://www.webdevelopment2.com/cakephp-auth-component-tutorial-1/
http://www.littlehart.net/atthekeyboard/2008/01/08/simple-user-registration-in-cakephp/
http://wiki.kabturek.info/authcomponent
http://www.cpa-lab.com/tech/AuthComponent%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9
Popularity: 69 %
by redgasuki 











[CakePHP]AuthComponentのパスワード暗号…
1.2系で追加されたAuthComponentは、認証関連の処理を一手に担ってくれる強力なコンポーネントですが、 AuthComponentのパスワード暗号化。登録注 (more…)
Cakeの1.1系から1.2系に移行しようと苦戦中のものですが、このような記事はもう、ホントありがたくて仕方ありません。
私のような難民はみんなあなた様に救われていることでしょう。
難民を救うことなどモチベーションにつながらないかもしれませんが、これからもこのような記事を書いていただけると、難民の一人としてとてもうれしく思います。
花粉や黄砂の舞う季節で、なにかとアルコールの摂取量も増えそうな今日この頃ですが、どうぞお体を大切に頑張ってください。
それでは。
モチベーション上がりまくりです。
コメントありがとうございました。
私も立派な難民・・・です。
今も、paginationをmodelに押し込みたいのですが、うまくいかなくて悩んでます。
わかったことは、みなさんとシェアしたいと思いますので、これからもよろしくお願いします。
本当に勝手に暗号化されるの??
どうやって?コンポーネントの配列にAuthが入ってるだけで?
処理の流れが分からない。
こんにちは、kofunさん
コメントありがとうござました。
Authcomponentも他のコンポーネントと同じで、用意されているフックを利用しています。
Authcomponentのstartupを覗くと、暗号化している部分が見えますよね。
beforeFilterでコンポーネントの設定→Authcomponentのstartupを実行(ここで暗号化など一連の作業)→controller(
ユーザ登録などのアクションの順番)で実行されます。
コンポーネントのフックについてはこちらが参考になると思います。
http://cakephp.jp/doc/ch09s02.html
startup以外のフックについてはhaltさんのエントリーが参考になります
http://project-p.jp/halt/anubis/blog_show/1008
なるほど参考になりました.やっぱりCakeは難しいですね.
[...] 【CakePHP】AuthComponentについてのまとめ その2【ちょっとしたコツ編】 http://blog.ne2ma2.com/archives/161 [...]
> ログインしているかどうか、チェック仕方は?
> $this->Auth->isAuthorized()
v1.2 rc2 の isAuthorized() の目的は、ソースに書いてある通り
| Determines whether the given user is authorized to perform an action.
で、その内部で Acl::check() が実行されています。
つまり、その時の ARO にその時の ACO (controller/action) が許可されてい
るかどうかを判定するために使うと思います。
ログインしているか否かは、
$user = $this->Auth->user()
if ($user)
{
//logged in
}
else
{
// not logged in
}
が宜しくないでしょうか?
こんにちは、custarさん
ご指摘ありがとうございます。
ご指摘の部分については、まさしくその通りです。
早速、記事の内容を修正致しました。
CakePHP Usersフォーラムに以前に似たような内容を書いていたのですが、そちらには
$this->Auth->user();
で書いてあったり・・・
自分の書いたものには責任を持たないと、いけませんね。
ご指摘、本当にありがとうございました。
どういたしまして。本ページを参考にされている方が多いので、
迅速で適切な処置だと思います。
それにしても、上記に書かれている通り、この辺の事に関しては「難しい」と
おっしゃる方が多いでしょうね。cakephp が難しいんじゃなくて、仕様を適切
に反映させた詳細なドキュメントが少なすぎる、と感じています。
私は Role をもたせた ACL で、Role ごとのアクセス制御に四苦八苦していま
す。Role 対 Role のアクセス制御です。結構面倒。
cakephp v2.0 では ACL が楽になってくれることを期待しています。
都合上、v1.2 を集中的に構造解析してるのですが、現在の cakephp の印象は
「入りやすく出にくい」です。使い始めるのは易しいが、きちんとしたものを
作るには、情報が少なすぎて形にならない。
zend も symfony も 1 年前に触れましたが、使い始めるのにこんなに手間がか
かるなんて!と腹を立てて止めましたが、今ならどうなのかな。cake は使い始
めはなんて簡単な、でしたが、今は情報不足に腹が立っています。
こんにちは、custarさん
コメントありがとうございます。
>>仕様を適切に反映させた詳細なドキュメントが少なすぎる、と感じています。
確かにそれはありますね。
詳しい仕様を知りたい場合、ググるよりも、ソースを読むほうが速いし、確実って感じはありますね。
最近もCakePHPのXMLクラスの仕様を理解しないで、simplexmlの代わりに使って、壮大にハマった経験があります。(ソースを見るとバグではなく、仕様・・・みたいですが)
やっぱりオープンソースなので、なければ自分たちで、ということになりますよね。
特に1.2は、まだRC版ですから。
個人的には、
http://book.cakephp.org/ja
をみんなで充実させるのが、一番良いと思います。
(私も協力したいと思っています)
[...] 参考:【CakePHP】AuthComponentについてのまとめ 【ざっくり基本編】 参考:【CakePHP】AuthComponentについてのまとめ その2【ちょっとしたコツ編】 [...]
最近CakePHPを使い始めた者です。
Authコンポーネントを使った場合のパスワード妥当性チェックの方法にハマってたどりつきました。
なるほど、modelと違う名前で受けるというのは気が付きませんでした。おかげで問題を解決出来ました。有難うございます。
自分で暗号化を行う方法も最初は分からずに苦労しました。(こちらは何とか自己解決できました)
これらは、まともなアプリを作る場合には必ず通ると思いますので、公式マニュアルにも記述が欲しい所ですね。
これからも有用な情報を期待しています!!
本当に有難うございました。
こんにちは、tamaさん
爆遅レスですみません。
すでにご存知かもしれませんが、
cookbookにも記述があります
http://book.cakephp.org/ja/view/172/%E8%AA%8D%E8%A8%BC
あわせて御覧ください
CakePHPのAuthComponent実装+ブラウザ閉じても認証保持
初心者がCakePHPを使った開発を進めます(これまでのCakePHP)。CakePHPガイドブックを参考に基本的なアプリができたので、これを自分色に染めていきます。まず認証周りを強化したい。そこ…
こんにちは。いつも参考にさせてもらっています。
$user = $this->Auth->user()
の後に”;”が抜けております。すぐに気付きますが、おそらくコピペで利用する人がほとんどだと思うので、念のため・・・
細かいことをいちいちと、失礼致しました。
こんにちは、nishiさん
コメント&ご指摘ありがとうございます。
さっそく反映させました。
ありがとうございました。
はじめまして。いつも参考にさせていただいてます。
上の方に引き続き、細かいことで恐縮なんですが、この記事の
「ユーザ追加用のcontroller(controllers/users_controller.ctp)」と書かれた枠内のソースを拝借して試してみようとしたところ、中括弧の数が合わない(開き括弧の方が1つ多い)ことに気づきました。
素晴らしい記事だけに、本来意図していたソースを正確に知りたいので(そして、僕は初心者で、残念ながらまだ自分の解釈に自信が持てないので)、折をみてご確認いただければと思います。
ひょっとして単に、いちばん最後に1つ、閉じ括弧を加えればいいだけ・・・なんでしょうか・・・??(不安
こんにちは、K さん
コメント&ご指摘ありがとうございます。
さっそく反映させました。
うーん、皆さんのおかげで修正されていますが、ここまで、間違いが多いと(汗
というか、今見るとちょっとひどいソースです。
1.2ぽくない書き方(1.2を使い始めたこところに書いた記事なので、と言い訳)、
今ならmodelにみんな書く、というレベルがcontrollerに書いてる・・・
そのうち、全面的に直そうかと、思います。