CakePHP1.3でWebアプリケーションを構築する上で、Authコンポーネントを使った管理画面を作ってみます。
前提として、adminコントローラ配下に認証をかけることにします。つまりCakePHPで構築したサイト内で「http://xxx.xxx.xxx/admin」にアクセスするためには管理者権限を必要とするようにします。
ユーザ管理テーブルを用意する
ユーザIDとパスワードを管理するテーブル「users」を用意します。
CREATE TABLE users ( id INTEGER(8) auto_increment PRIMARY KEY, username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL, date_create VARCHAR(19) NOT NULL, date_update TIMESTAMP NOT NULL );
最低限「ユーザID」と「パスワード」の2カラムを用意します。その他のカラムは任意です。また、カラム名は変更可能ですが、デフォルトの「username」「password」とします。今回は記述しませんが、カラム名を変更するためにはコントローラ内で設定が必要です。
今回、このテーブルへのINSERTは手動で行います。パスワードはハッシュ値を登録します。
ユーザ管理テーブルのモデルを用意する
過去の記事にも書きましたが、このときモデル名は「User」になります。今回はモデルで特別な設定はしません。
class User extends AppModel { var $name = 'User'; }
adminコントローラを用意する
adminコントローラを用意します。
class AdminController extends AppController { public $name = "Admin"; public $uses = array('User'); public $components = array('Auth'); function beforeFilter(){ $this->Auth->userModel = 'User'; $this->Auth->loginAction = array( 'controller' => 'admin', 'action' => 'login' ); $this->Auth->loginRedirect = array( 'controller' => 'admin', 'action' => 'index' ); $this->Auth->logoutRedirect = array( 'controller' => 'admin', 'action' => 'login' ); $this->Auth->allow('login', 'logout'); $this->Auth->loginError = 'ユーザ名もしくはパスワードに誤りがあります'; $this->Auth->authError = '管理者としてログインする必要があります'; } function index(){ // 略 } function login(){ // 略 } function logout(){ // 略 } }
4、5行目でモデル「User」と組込みコンポーネント「Auth」を指定します。
7行目beforeFilterで、adminコントローラのログイン画面を「login」、ログイン後のリダイレクト先画面を「index」、ログアウト画面を「logout」と指定します。
21行目でadminコントローラ内でも「login」「logout」画面は認証の必要がないことを指定します。
22行目ではログイン時に誤りがあった場合、23行目では未認証状態で管理画面にアクセスした場合のエラーメッセージを任意に変更しています。ちなみに、loginErrorのデフォルトメッセージは「Login failed. Invalid username or password.」、authErrorは「You are not authorized to access that location.」となっています。
ログイン画面を作る
ログイン画面は「http://xxx.xxx.xxx/admin/login」になります。認証前に他の画面にアクセスしても、このログイン画面にジャンプするようになります。
ログイン画面はFormヘルパーで作ることもできるようですが、レイアウトの自由度を高めるためにも、今回は以下のように独自で記述します。
<?php echo $session->flash('auth'); ?> <form action="login" method="post"> <table> <tr> <th>ユーザ名</th><td><input type="text" name="data[User][username]" /></td> </tr> <tr> <th>パスワード</th><td><input type="password" name="password" /></td> </tr> <tr> <th></th><td><input type="submit" value="ログイン" /></td> </tr> </table> </form>
先ほどアクションで設定したような認証時のエラーメッセージを出力するためには、「echo $session->flash(‘auth’);」を記述します。
2行目のように、アクション「login」でログイン処理を行う場合、フォームのactionに「login」を指定します。
また、ユーザ名のnameを「data[User][username]」とします。後述しますが、このデータ構造で認証を実行するので、予め指定しておくことで認証処理をスムーズに行うことができます。また、同じ理由でパスワードも「data[User][password]」としたいのですが、なぜかこの型にするとパスワードがPOSTできないため、とりあえず「password」とします。
ログイン処理
アクション「login」にログイン処理を記述します。
function login(){ if(isset($this->params['form']['password'])){ $this->data['User']['password'] = $this->Auth->password($this->params['form']['password']); // ログイン成功 if($this->Auth->login($this->data)){ $this->redirect('/admin'); } else{ // ログイン失敗 } } }
2行目は、ログインボタンが押され、postされた時にログイン処理を実行します。
4行目は、先ほど述べたように「data[User][password]」としてpostデータを受けたいのですが、なぜかうまくいかないため、「$this->params[‘form’][‘password’]」として受けます。さらに、関数「$this->Auth->password」を使ってハッシュ値を得ます。
7行目は、「data[User][username]」にユーザID、「data[User][password]」にパスワードをセットした状態で、関数「$this->Auth->login」を使って認証を試みます。これは、Authコンポーネントにより、ユーザ管理テーブルに問い合わせ、認証情報が正しいかどうかを判定します。
認証が通った場合に自動的にクッキーに認証状態が保持されます。また、その後にアクション「index」にジャンプすると思っていたのですが。これもうまくいかないため、8行目にリダイレクトを記述します。
これで、Authコンポーネントを使った認証のしくみは一通り構築できました。
後は、例えばアクション「kanri1」「kanri2」「kanri3」といった具合にページを増やしていくことが可能です。これらのページには特別処理を記述する必要はなく、一度認証を通過してしまえば「http://xxx.xxx.xxx/admin/kanri1」というようにしてアクセス可能です。「logout」アクションにアクセスするまでは、管理者権限は保持されます。
ただ、今回いくつか意図しない挙動が見られたので、もう少し調査、改良を試みたいと思います。
コメントする