この記事では、 
Zend_Authコンポーネントの機能の概要を説明し、Zend Frameworkに基づくアプリケーションでのユーザー認証の実装の一般的な考え方を示します。 与えられた例の基礎として、記事
「Introduction to Zend Framework」の資料
が使用されました 。 サンプルはZend Frameworkバージョン0.9、0.9.1、0.9.2でテストされており、新しいバージョンでは動作する可能性が高いですが、以前のバージョンでは動作しません。 
投稿者:ロブアレン、 
http://akrabat.comオリジナル: http : //akrabat.com/zend-auth-tutorial翻訳: Alexander Musaev、 
http : //paradigm.ru
印刷用のPDFバージョン: http : //archive.paradigm.ru/zend_auth.pdf始める前に
この例で使用するユーザー認証メカニズムの実装は、PHPセッションに基づいています。 
php.ini session.save_pathパラメーターが、Webサーバーが書き込み可能なディレクトリに設定されていることを確認してください。
認証
認証または認証は、サブジェクトと、一意の情報を使用して偽装しようとしているサブジェクトの適合性を検証するための手順です。 この手順は、識別(情報のやり取りの対象の認識)および承認(システムリソースへのアクセス権の検証)とは区別する必要があります。
Webアプリケーションのコンテキストでは、認証は通常、ユーザーがWebサーバー上の自分のアカウントと名前(「ログイン」)およびパスワードを照合するかどうかをチェックすることを意味します。 Zend Frameworkに基づいたこのようなメカニズムの実装の例として、CDデータベースにこのチェックを追加します(記事「Introduction to Zend Framework」で実装されたWebアプリケーション)。
これには次のものが必要です。
- ユーザー用のデータベースにテーブルを作成します(そして、新しいアカウントを追加します)。
 - ログインフォームを作成します。
 - 出入りするアクションを含むコントローラーを実装します。
 - ページテンプレートの一般的なフラグメントにログアウトする機能を追加します。
 - ユーザーが何らかのアクションを実行できるようにする前に、ユーザーがログインしていることの確認を追加します。
 
ユーザー表
最初に必要なのは、ユーザーアカウントを保存するためのデータベース内のテーブルです。 彼女のスキームは次のようになります。
| フィールド | 種類 | ヌル? | フィールドオプション | 
|---|
| id | 整数 | いや | 主キー、自動インクリメント | 
| ユーザー名 | バルチャー(50) | いや | 一意のキー | 
| パスワード | バルチャー(50) | いや | - | 
| 実名 | バルチャー(100) | いや | - | 
MySQLを使用する場合、このようなテーブルは次のクエリで作成できます。
CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
real_name VARCHAR(100) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY username (username)
)
テストユーザーアカウントを追加する必要があります。
INSERT INTO users (id, username, password, real_name)
VALUES (1, 'rob', 'rob', 'Rob Allen');
MySQLクライアントプログラムを使用してこれらのSQLクエリを実行します。 ユーザー名とパスワードは、必要に応じて他の値に変更できます。
ブートファイル
システムへのユーザーの登録(エントリと終了)を追跡できるようにするには、PHPセッションのメカニズムを使用する必要があります。 Zend Frameworkは、便利な作業のために、特別なクラス
Zend_Session_Namespace提供してい
Zend_Session_Namespace 。
ブートストラップファイルに次の変更を加える必要があります。
zf-tutorial/index.php:...
Zend_Loader::loadClass('Zend_Db_Table');
Zend_Loader::loadClass('Zend_Debug');
Zend_Loader::loadClass('Zend_Auth');
// load configuration
...
// setup database
$dbAdapter = Zend_Db::factory($config->db->adapter,
$config->db->config->asArray());
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Zend_Registry::set('dbAdapter', $dbAdapter);
// setup controller
$frontController = Zend_Controller_Front::getInstance();
...
ここで必要なことは、 
Zend_Authクラス
Zend_Auth接続され、 
Zend_Authデータベース
dbAdapter登録されていることを確認することだけです。 このアダプターは、後で許可コントローラーからアクセスする必要があるため、レジストリーに保管されます。
承認コントローラー
入力アクションと出力アクションをグループ化するには、特別なコントローラーが必要です。 
AuthControllerという名前を付けることは論理的
AuthController 。 コンストラクターで実装を開始し、デフォルトのアクション( 
indexAction() )を定義しましょう。
zf-tutorial/application/controllers/AuthController.php:<?php
class AuthController extends Zend_Controller_Action
{
function init()
{
$this->initView();
$this->view->baseUrl = $this->_request->getBaseUrl();
}
function indexAction()
{
$this->_redirect('/');
}
}
コントローラークラスのコンストラクターで、ビューが初期化
baseUrl 、 
baseUrl変数の値が
baseUrlます。 コンストラクターに加えて、 
indexAction()アクションがクラスで定義され
Zend_Controller_Action 。これは、 
Zend_Controller_Actionすべての子孫にとって必須の要件です。 
loginAction()および
logoutAction()のみを使用することを考慮すると、デフォルトのアクションは必要ないため、対応するURLからサイトのメインページにユーザーをリダイレクトします。
ログイン
システムに入るには、特別なフォームが必要です。 
AuthController login AuthControllerは、 
IndexControllerアクションがフォームで
IndexControllerするのと同じ方法でそれと対話します。 フォームテンプレートは、ファイル
views/scripts/auth/login.phtmlにあり、そこからのデータは
AuthController::loginAction()メソッドによって処理されます。
ログインフォームは非常にシンプルで、ユーザー名とパスワード用の2つのフィールドのみが含まれています。
zf-tutorial/application/views/scripts/auth/login.phtml:<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php if(!empty($this->message)) :?>
<div id="message">
<?php echo $this->escape($this->message);?>
</div>
<?php endif; ?>
<form action="<?php echo $this->baseUrl ?>/auth/login" method="post">
<div>
<label for="username">Username</label>
<input type="text" name="username" value=""/>
</div>
<div>
<label for="password">Password</label>
<input type="password" name="password" value=""/>
</div>
<div id="formbutton">
<input type="submit" name="login" value="Login" />
</div>
</form>
<?php echo $this->render('footer.phtml'); ?>
テンプレートには、ページの最初と最後にそれぞれ
header.phtmlと
footer.phtml表示されます。 変数
$this→messageメッセージからの
$this→messageは、その値が空でない場合にのみ表示されることに注意してください。 この変数は、ログイン中にエラーが発生し、ユーザーがそれを報告する必要がある場合に使用されます。 テンプレートの残りの部分は、ログインフォーム自体です。
フォームの準備ができたので、それを操作するコントローラーの作成に進みます。
zf-tutorial/application/controllers/AuthController.php:class AuthController extends Zend_Controller_Action
{
...
function loginAction()
{
$this->view->message = '';
$this->view->title = "Log in";
$this->render();
}
}
フォームを表示するには、タイトルとメッセージ本文を設定する必要があります。その後、URLをクリックしてフォームを表示できます 
http://zf-tutorial/auth/login http://zf-tutorial/auth/login 。 この場合、送信されたデータをどのように処理するのでしょうか? これを行うには、 
IndexControllerレコードフォームを編集および追加する場合に使用したのと同じメソッドを使用します。 つまり、サーバーへのアクセス方法がPOSTの場合にのみ、データ処理が実行されます。 それ以外の場合、 
loginアクションは単にフォームを返し
login 。 
loginAction()必要な変更を以下に示します。
zf-tutorial/application/controllers/AuthController.php:class AuthController extends Zend_Controller_Action
{
...
function loginAction()
{
$this->view->message = '';
if ($this->_request->isPost()) {
// collect the data from the user
Zend_Loader::loadClass('Zend_Filter_StripTags');
$f = new Zend_Filter_StripTags();
$username = $f->filter($this->_request->getPost('username'));
$password = $f->filter($this->_request->
getPost('password'));
if (empty($username)) {
$this->view->message = 'Please provide a username.';
} else {
// setup Zend_Auth adapter for a database table
Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
$dbAdapter = Zend_Registry::get('dbAdapter');
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');
// Set the input credential values
// to authenticate against
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
// do the authentication
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
// success: store database row to auth's storage
// system. (Not the password though!)
$data = $authAdapter->getResultRowObject(null, 'password');
$auth->getStorage()->write($data);
$this->_redirect('/');
} else {
// failure: clear database row from session
$this->view->message = 'Login failed.';
}
}
}
$this->view->title = "Log in";
$this->render();
}
}
上記のコードをステップごとに検討してください。
// collect the data from the user
Zend_Loader::loadClass('Zend_Filter_StripTags');
$f = new Zend_Filter_StripTags();
$username = $f->filter($this->_request->getPost('username'));
$password = $f->filter($this->_request->getPost('password'));
if (empty($username)) {
$this->view->message = 'Please provide a username.';
} else {
...
ここでは、いつものように、POST配列からユーザー名とパスワードを抽出し、HTMLフィルターでそれらの値を処理します。 この場合に使用される
getPost()関数は、パラメーターで指定された変数の存在を自動的にチェックし、POSTで変数が見つからない場合は空の値を返します。
認証プロセスは、ユーザー名が指定されている場合にのみ続行されます。 空の場合、 
Zend_Auth認証しようとすると例外がスローされます。
// setup Zend_Auth adapter for a database table
Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
$dbAdapter = Zend_Registry::get('dbAdapter');
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');
Zend_Authは、アダプターサブシステムを使用して認証データを操作します。 このようなアダプターは、リレーショナルデータベース、LDAP、シンプルファイルなどの異種データストアへの統合されたインターフェイスを提供します。 この例では、データベースがこの目的に使用されるため、 
Zend_Auth_Adapter_DbTableアダプターが
Zend_Auth_Adapter_DbTableます。 初期化するには、データベースパラメータ(ユーザーテーブルの名前とそのフィールドの名前)を設定する必要があります。
// Set the input credential values to authenticate against
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
また、フォームに入力されたユーザー名とパスワードの正確な値をアダプターに渡す必要があります。
// do the authentication
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
認証手順自体を実行するために、 
Zend_Authクラスの
authenticate()メソッドの呼び出しが
Zend_Authます。 この場合、認証結果はセッションに自動的に保存されます。
if ($result->isValid()) {
// success : store database row to auth's storage
// system. (not the password though!)
$data = $authAdapter->getResultRowObject(null,
'password');
$auth->getStorage()->write($data);
$this->_redirect('/');
認証が成功した場合、データベースのユーザーアカウントは
Zend_Authシングルトン内に完全に保存されます(もちろん、パスワードは除きます)。
} else {
// failure: clear database row from session
$this->view->message = 'Login failed.';
}
}
ユーザー名とパスワードの検証に合格しなかった場合は、変数
messageを通じてユーザーに通知し
message 。 これで、ログインの認証プロセスが完了しました。
出口
ログアウトはログインよりもはるかに簡単です。 必要なのは、 
Zend_Authシングルトン内のデータをクリアすることだけです。 これは、 
logoutAction()コントローラーの
logoutAction()アクションで実装されます。 したがって、終了するには、URLに移動するだけです。 
http://zftutorial/auth/logout http://zftutorial/auth/logout 。
zf-tutorial/application/controllers/AuthController.php:class AuthController extends Zend_Controller_Action
{
...
function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('/');
}
}
logoutAction()関数は非常に単純なので、コメントするものはまったくありません。
ユーザーがクリックしてWebアプリケーションを終了できる特別なリンクをユーザーに提供する必要があります。 最も簡単な方法は、 
footerテンプレート内です。 さらに、承認が成功したことを確認するために、ユーザーに名前を通知します。 ユーザー名は、対応するデータベーステーブルの
real_nameフィールドに保存され、 
Zend_Authからアクセスできます。 最初に行う必要があるのは、この値をビューに渡すことです。これは、 
IndexController()コントローラーの
init()関数内で行い
init() 。
zf-tutorial/application/controllers/IndexController.php:class IndexController extends Zend_Controller_Action
{
function init()
{
$this->initView();
Zend_Loader::loadClass('Album');
$this->view->baseUrl = $this->_request->getBaseUrl();
$this->view->user = Zend_Auth::getInstance()->getIdentity();
}
...
}
Zend_Authがシングルトンであると非常に便利です。 それ以外の場合、この場合、その内容をレジストリに保存する必要があります。
次に、 
footer.phtmlファイルに変更を加える必要があります。
zf-tutorial/application/views/footer.phtml:<?php if($this->user) : ?>
<p id="logged-in">Logged in as <?php
echo $this->escape($this->user->real_name);?>.
<a href="<?php echo $this->baseUrl ?>/auth/logout">Logout</a></p>
<?php endif; ?>
</div>
</body>
</html>
上記のコードには、根本的に新しいものは含まれていません。 
escape()を使用して、ブラウザにユーザー名が正しく表示されることを確認します。 
baseUrl変数の値は、リンクを正しく形成するために使用されます。
ログアウト機能の準備ができました。
アクション保護
私たちがやるべきことは、ユーザーがログインする前にアクションが利用できないことを確認することだけです。
zf-tutorial/application/controllers/IndexController.php:class IndexController extends Zend_Controller_Action
{
...
function preDispatch()
{
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity()) {
$this->_redirect('auth/login');
}
}
...
}
標準名が
preDispatch()関数は、コントローラーアクションの前に自動的に呼び出されます。 
hasIdentity()オブジェクトの
hasIdentity()メソッドを使用して、ログインが完了したかどうかを確認します。 そして、そうでない場合は、ユーザーを
auth/loginリダイレクトし
auth/login 。
これで承認作業が完了しました。
おわりに
Zend Frameworkに基づくユーザー認証関数の実装の上記の例は非常に単純ですが、 
Zend_Authはいくつかのコントローラーでより複雑なアプリケーションを保護するために使用できる多くの便利な機能がまだあることを理解する必要があります。 
Zend_Aclコンポーネントに実装されている承認システムも影響を受けませんでした。 後者は
Zend_Authと組み合わせて使用し、ユーザーアクセスレベルをアクションまたはデータに区別するように設計されていますが、これは別の議論のトピックです。
元の記事に関するすべてのコメントは、rob @ akrabat.comの著者に送信できます。 ロシア語の翻訳に関するコメントは、musayev @ yandex.ruに送信してください。
更新:記事のプログラムの例を
含むアーカイブは、著者のウェブサイト
zend_auth-tutorial_104.zipにあります。