3.2. データベースのテーブルを用いた認証

3.2.1. 導入

Zend_Auth_Adapter_DbTable は、 データベースのテーブルに保存された証明情報に基づいた認証の機能を提供します。 Zend_Auth_Adapter_DbTable のコンストラクタには Zend_Db_Adapter_Abstract のインスタンスを渡す必要があるので、 各インスタンスは特定のデータベース接続に関連付けられます。 コンストラクタではその他の設定オプションも指定することができます。 これらは個別にインスタンスメソッドで指定することもできます。

次のような設定オプションが使用可能です。

  • tableName: これはデータベースのテーブル名です。証明情報が含まれ、 認証クエリの問い合わせ先となるテーブル名を指定します。

  • identityColumn: これは、ID を表すデータベーステーブルのカラム名です。 このカラムには、ユーザ名やメールアドレスのような一意な値が含まれている必要があります。

  • credentialColumn: これは、証明情報を表すデータベーステーブルのカラム名です。 単純な ID およびパスワードによる認証方式では、この値がパスワードに対応します。 credentialTreatment オプションも参照ください。

  • credentialTreatment: 多くの場合、パスワードやその他機密情報は、何らかの関数やアルゴリズムで 暗号化、ハッシュ化、符号化、ぼかしなどの処理が行われています。 これらの処理を表すパラメータつきの文字列、たとえば 'MD5(?)''PASSWORD(?)' を指定することで、 証明データに対して任意の SQL を適用できるようになります。 これらの関数は RDBMS によって異なります。 データベースシステムでどのような関数が使えるのかについては、 データベースのマニュアルをご確認ください。

例 3.3. 基本的な使用法

導入部で説明したとおり、Zend_Auth_Adapter_DbTable のコンストラクタには Zend_Db_Adapter_Abstract のインスタンスを渡す必要があります。これは、認証アダプタのインスタンスと 関連付けるデータベース接続を表します。 まず、データベース接続を作成する必要があります。

次のコードは、メモリ内データベースのアダプタを作成し、 簡単なテーブルスキーマを作成し、そして後で認証クエリを実行するための行を追加します。 この例を実行するには、PDO SQLite 拡張モジュールが有効になっている必要があります。

<?php
// メモリ内で SQLite データベース接続を作成します
require_once 'Zend/Db/Adapter/Pdo/Sqlite.php';
$dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:'));

// 単純なテーブルを作成するクエリ
$sqlCreate = 'CREATE TABLE [users] ( '
           . '[id] INTEGER  NOT NULL PRIMARY KEY, '
           . '[username] VARCHAR(50) UNIQUE NOT NULL, '
           . '[password] VARCHAR(32) NULL, '
           . '[real_name] VARCHAR(150) NULL)';

// 認証情報テーブルを作成します
$dbAdapter->query($sqlCreate);

// 認証を成功させるために行を追加します
$sqlInsert = 'INSERT INTO users (username, password, real_name) '
           . 'VALUES ("my_username", "my_password", "My Real Name")';

// データを挿入します
$dbAdapter->query($sqlInsert);

データベース接続およびテーブルが使用可能となったので Zend_Auth_Adapter_DbTable のインスタンスが作成できます。 設定オプションの値は、コンストラクタで渡すか、 あるいはインスタンスを作成した後に設定用メソッドで指定します。

<?php
require_once 'Zend/Auth/Adapter/DbTable.php';

// コンストラクタにパラメータを渡し、インスタンスを設定します
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter, 'users', 'username', 'password');

// あるいは、設定用メソッドでインスタンスの設定を行います
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
            ->setIdentityColumn('username')
            ->setCredentialColumn('password');

この時点で、認証アダプタのインスタンスは認証クエリを受け付ける準備ができました。 認証クエリを処理するには、入力された証明情報をアダプタに渡してから authenticate() メソッドをコールします。

<?php
// 入力情報 (ログインフォームからの値など) を設定します
$authAdapter->setIdentity('my_username')
            ->setCredential('my_password');

// 認証クエリを実行し、結果を保存します
$result = $authAdapter->authenticate();

認証結果オブジェクトでの getIdentity() メソッドに加え、Zend_Auth_Adapter_DbTable は認証の成功時にテーブルの行を取得する機能もサポートしています。

<?php
// ID を表示します
echo $result->getIdentity() . "\n\n";

// 結果の行を表示します
print_r($identity);

/* 出力結果
my_username

Array
(
    [id] => 1
    [username] => my_username
    [password] => my_password
    [real_name] => My Real Name
)
*/

テーブルの行には証明情報が含まれているので、 予期せぬアクセスからその内容を守ることが重要となります。

3.2.2. 応用例: 持続的な DbTable 結果オブジェクト

デフォルトでは Zend_Auth_Adapter_DbTable は、 認証に成功した際に認証情報を返します。場合によっては、 Zend_Auth の持続ストレージの仕組みを利用して 別の有用な情報を格納したいこともあるでしょう。その場合は、 getResultRowObject() メソッドを使用して stdClass オブジェクトを返します。 次のコードで、使用法をご確認ください。

<?php
// Zend_Auth_Adapter_DbTable による認証を行います
$result = $this->_auth->authenticate($adapter);

if ($result->isValid()) {

    // 認証情報をオブジェクトとして保存し、username と real_name のみを返します
    $this->_auth->getStorage()->write($adapter->getResultRowObject(array('username', 'real_name'));

    // 認証情報をオブジェクトとして保存し、password のみを省略します
    $this->_auth->getStorage()->write($adapter->getResultRowObject(null, 'password'));

    /* ... */

} else {

    /* ... */

}