忍者ブログ
自分なりの目線で情報を発信します。
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

会社でZendFrameworkを使うことになった(なってしまった)ので、
Zend_Authを使ってログインページを作ってみました。

Zend_Auth(本家HP)
http://framework.zend.com/manual/ja/zend.auth.html

Zend_Authでは、ID・パスワードを保持する方法にいくつか種類があるそうなのですが、
普通にデータベースのテーブルに保持する方法を選択しました。
DBはMySQLで、ログイン情報を保持するテーブル定義は以下の通りです。

テーブル名
  • admin
カラム定義
  • loginid INT
  • password VARCHAR(16)
  • personname VARCHAR(32)


■ログインページ(login.php)
  1. <html>
  2. <head>
  3.   <meta http-equiv="Content-Type" content="text/html; charset=utf8">
  4.   <title>ログイン</title>
  5. </head>
  6. <body>
  7.   <h1>ログイン</h1>
  8.   <form action="/auth/login" method="post" name="loginForm">
  9.     <table summary="ログインフォーム">
  10.       <thead></thead><tfoot></tfoot>
  11.       <tbody>
  12.         <tr>
  13.           <th>ログインID</th>
  14.           <td>
  15.             <input type="text" name="loginid">
  16.           </td>
  17.         </tr>
  18.         <tr>
  19.           <th>パスワード</th>
  20.           <td>
  21.             <input type="password" name="password">
  22.           </td>
  23.         </tr>
  24.       </tbody>
  25.     </table>
  26.     <input type="submit" value="ログイン">
  27.   </form>
  28. </body>
  29. </html>

ログインIDとパスワードを入力して、認証用コントローラーにsubmitするだけです。


■認証用コントローラー(AuthController.php)

  1. <?php
  2.  
  3. class AuthController extends Zend_Controller_Action
  4. {
  5.     const AUTH_TABLE_NAME = 'admin';
  6.     const AUTH_ID_NAME    = 'loginid';
  7.     const AUTH_PASS_NAME  = 'password';
  8.  
  9.     private $errmsg = array();
  10.  
  11.     // デフォルトアクション
  12.     public function indexAction()
  13.     {
  14.         // ログインページへ
  15.         return $this->_forward('login-page');
  16.     }
  17.  
  18.     // ログインページ
  19.     public function loginPageAction()
  20.     {
  21.         $this->renderScript('login.php');  // ログインページのビュースクリプトを指定
  22.     }
  23.  
  24.     // ログイン
  25.     public function loginAction()
  26.     {
  27.         $dbAdapter = new Zend_Db_Adapter_Pdo_Mysql(array(
  28.                             'host'     => 'localhost',
  29.                             'username' => 'xxxx',
  30.                             'password' => 'xxxx',
  31.                             'dbname'   => 'xxxx'
  32.                          ));
  33.         $authAdapter = new Zend_Auth_Adapter_DbTable(
  34.                                $dbAdapter,
  35.                                self::AUTH_TABLE_NAME,
  36.                                self::AUTH_ID_NAME,
  37.                                self::AUTH_PASS_NAME);
  38.         // リクエストパラメータ
  39.         $loginid  = $this->getRequest()->getParam('loginid', '');
  40.         $password = $this->getRequest()->getParam('password', '');
  41.         if ($loginid === '' || $password === '') {
  42.             // そもそもIDまたはパスワードがない →認証NG →ログインページへ
  43.             return $this->_forward('login-page');
  44.         }
  45.         // IDとパスワードをセットする
  46.         $authAdapter->setIdentity($loginid);
  47.         $authAdapter->setCredential($password);
  48.         // 認証する
  49.         $result = $authAdapter->authenticate();
  50.         if ($result->isValid() === FALSE) {
  51.             // 認証NG →ログインページへ
  52.             return $this->_forward('login-page');
  53.         }
  54.         // 認証OK →認証済み情報をストレージ(セッション)に格納
  55.         $storage = Zend_Auth::getInstance()->getStorage();
  56.         $resultRow = $authAdapter->getResultRowObject(array('loginid', 'personname'));
  57.         $storage->write($resultRow);
  58.         // セッションID再生成
  59.         $ret = session_regenerate_id(true);
  60.         // ログイン後のデフォルトアクションへ
  61.         return $this->_forward('index', 'admin');
  62.     }
  63.  
  64.     // ログアウト
  65.     public function logoutAction()
  66.     {
  67.         // 認証済み情報をストレージから削除
  68.         $authStorage = Zend_Auth::getInstance()->getStorage();
  69.         $authStorage->clear();
  70.         // ログインページへ
  71.         return $this->_forward('login-page');
  72.     }
  73.  
  74. }
  75.  
  76. // end of file

Zend_Auth_Adapter_DbTableに、データベースやテーブル情報を設定した上で、
リクエストで受け取ったIDとパスワードを認証します。
 
認証が無事終わったら、認証済み情報をストレージに格納しています。
このストレージというのは、PHPのセッションのことです。
 
明示的にストレージへの格納処理を書かなくとも、
Zend_Authは自動的にログイン時に入力されたIDをセッションに保存してくれるのですが、
ID以外の情報も参照したいため、今回は明示的に処理を記述しています。
 
少しはセキュリティを考慮したいので、セッションIDを再生成しています。

 
■ログイン後の各種アクション提供コントローラー(AdminController.php)
  1. <?php
  2.  
  3. class AdminController extends Zend_Controller_Action
  4. {
  5.     // 認証済み情報
  6.     private $authInfo = array();
  7.  
  8.     // アクション前処理
  9.     public function preDispatch()
  10.     {
  11.         // 認証済み情報を取り出す
  12.         $authStorage = Zend_Auth::getInstance()->getStorage();
  13.         if ($authStorage->isEmpty()) {
  14.             // 認証済み情報がない →ログインページへ
  15.             return $this->_forward('login-page', 'auth');
  16.         }
  17.         $this->authInfo = (array)$authStorage->read();
  18.     }
  19.  
  20.     // デフォルトアクション
  21.     public function indexAction()
  22.     {
  23.         // デフォルト処理いろいろ
  24.     }
  25.  
  26.     // その他のアクション
  27.     public function otherAction()
  28.     {
  29.         // その他の処理いろいろ
  30.     }
  31.  
  32. // end of file

ログイン後のアクションを実行前には、常に認証済みであるかの確認を行いたいので、
preDispatchメソッドに認証済みの確認処理を記述しています。
 
認証用のコントローラーと、認証後のコントローラーを分けることで、
preDispatchに認証済みの確認処理が書きやすくしています。
 
※認証処理を行うコントローラーのpreDispatchに
認証済み確認処理を書いて、NGならログインページに飛ばすというような書き方をすると
 preDispatchで認証確認エラー
  →ログインページへ
   →ログインページの前処理であるpreDispatchで認証確認エラー
    →ログインページへ
     →ログインページの前処理であるpreDispatchで認証確認エラー
のような感じの無限ループになります・・・orz
これを避ける方法はいくらでもあると思いますが、少しはまったので。。。
 
 
うん、中々シンプルにログイン処理が作れたかなと思います。
PR
お知らせ
プロフィール
HN:
shusatoo
性別:
男性
自己紹介:
基本PHP。JavaScriptちょっとだけ。Javaをほんの少し。
おすすめ本
最新コメント
[10/09 shusatoo]
[10/09 misney]
最新トラックバック
カレンダー
10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
ブログ内検索
カウンター
アク解アナライズ
バーコード
ビジター

Copyright © [ 開発メモるアル ] All rights reserved.
Special Template : 忍者ブログ de テンプレート
Special Thanks : 忍者ブログ
Commercial message : [PR]