1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 20763 -->
4 <sect1 id="zend.auth.introduction">
9 <classname>Zend_Auth</classname> は、認証のための <acronym>API</acronym> を提供します。
10 また、一般的な使用例に対応する具象認証アダプタも用意しています。
14 <classname>Zend_Auth</classname> が扱うのはあくまでも <emphasis>認証 (authentication)</emphasis>
15 であり、<emphasis>承認 (authorization)</emphasis> ではありません。
16 認証 (authentication) とはつまり、あるエンティティが何者であるのかを示す
17 (識別する) ことです。これを、なんらかの条件にもとづいて行います。
18 承認 (authorization) とは、あるエンティティが他のエンティティに対して
19 アクセスしたり何らかの操作をしたりする権限があるかどうかを判定する処理です。
20 これは <classname>Zend_Auth</classname> の対象外となります。
21 Zend Framework における認証やアクセス制御の詳細については、
22 <link linkend="zend.acl"><classname>Zend_Acl</classname></link> を参照ください。
27 <classname>Zend_Auth</classname> クラスはシングルトンパターン
29 を実装しており、静的メソッド <methodname>getInstance()</methodname> でそれを使用します。
30 つまり、<emphasis>new</emphasis> 演算子や
31 <emphasis>clone</emphasis> キーワードは <classname>Zend_Auth</classname>
32 クラスでは動作しないということです。そのかわりに
33 <methodname>Zend_Auth::getInstance()</methodname> を使用します。
37 <sect2 id="zend.auth.introduction.adapters">
42 <classname>Zend_Auth</classname> アダプタの使用目的は、
43 <acronym>LDAP</acronym> や <acronym>RDBMS</acronym> あるいはファイル
44 のような特定の型の認証サービスに対する認証を行うことです。
45 アダプタによってそのオプションや挙動は大きくことなるでしょうが、
46 いくつかの基本処理は、あらゆる認証アダプタで共通となります。
47 たとえば認証条件 (いわゆる ID) を受け取り、
49 結果を返すという処理は、すべての <classname>Zend_Auth</classname> アダプタで共通です。
53 各 <classname>Zend_Auth</classname> アダプタクラスは、<classname>Zend_Auth_Adapter_Interface</classname>
54 を実装しています。このインターフェイスで定義されているメソッドが
55 <methodname>authenticate()</methodname> で、アダプタクラスは
56 認証クエリを実行するためにこれを実装する必要があります。
57 各アダプタクラスは、<methodname>authenticate()</methodname>
58 をコールする前に準備を済ませておく必要があります。
59 つまり、アダプタ側で用意しなければならない機能としては
60 認証条件 (ユーザ名およびパスワードなど) の取得や
62 (データベースのテーブルを使用するアダプタならデータベースへの接続設定など)
68 これはユーザ名とパスワードを受け取って認証を行います。
69 その他の詳細、例えば認証サービスへの実際の問い合わせなどは、
73 <programlisting language="php"><![CDATA[
74 class MyAuthAdapter implements Zend_Auth_Adapter_Interface
77 * 認証用のユーザ名とパスワードを設定します
81 public function __construct($username, $password)
89 * @throws Zend_Auth_Adapter_Exception が、認証処理をできなかった場合に発生します
90 * @return Zend_Auth_Result
92 public function authenticate()
100 docblock コメントで説明しているとおり、
101 <methodname>authenticate()</methodname> は
102 <classname>Zend_Auth_Result</classname> (あるいは <classname>Zend_Auth_Result</classname> の派生クラス)
103 のインスタンスを返す必要があります。何らかの理由で認証の問い合わせができなかった場合は、
104 <methodname>authenticate()</methodname> は
105 <classname>Zend_Auth_Adapter_Exception</classname>
106 から派生した例外をスローしなければなりません。
111 <sect2 id="zend.auth.introduction.results">
116 <classname>Zend_Auth</classname> アダプタは、<methodname>authenticate()</methodname> の結果として
117 <classname>Zend_Auth_Result</classname> のインスタンスを返します。
118 これにより、認証を試みた結果を表します。アダプタのインスタンスを作成した際に
119 <classname>Zend_Auth_Result</classname> オブジェクトが作成され、
120 以下の 4 つのメソッドで <classname>Zend_Auth</classname> アダプタの結果に対する共通の操作ができます。
126 <methodname>isValid()</methodname> - その結果が
127 認証の成功を表している場合にのみ <constant>TRUE</constant> を返します。
132 <methodname>getCode()</methodname> - <classname>Zend_Auth_Result</classname> の定数を返します。
133 これは、認証に失敗したのか成功したのかを表すものです。
134 これを使用する場面としては、認証の結果をいくつかの結果から区別したい場合などがあります。
135 これにより、たとえば認証結果について、より詳細な情報を管理することができるようになります。
136 別の使用法としては、ユーザに示すメッセージを変更し、より詳細な情報を伝えられるようにすることなどがあります。
137 しかし、一般的な「認証失敗」メッセージではなく
138 ユーザに対して詳細な情報を示す際には、そのリスクを知っておくべきです。
144 <methodname>getIdentity()</methodname> - 認証を試みた ID 情報を返します。
149 <methodname>getMessages()</methodname> - 認証に失敗した場合に、
156 認証の結果によって処理を分岐させ、より決め細やかな処理を行いたいこともあるでしょう。
157 有用な処理としては、たとえば間違ったパスワードを繰り返し入力したアカウントをロックしたり、
158 存在しない ID を何度も入力した IP アドレスに印をつけたり、
159 ユーザに対してよりわかりやすいメッセージを返したりといったことがあります。
163 <programlisting language="php"><![CDATA[
164 Zend_Auth_Result::SUCCESS
165 Zend_Auth_Result::FAILURE
166 Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
167 Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
168 Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
169 Zend_Auth_Result::FAILURE_UNCATEGORIZED
173 次の例は、結果コードを処理する方法を示すものです。
176 <programlisting language="php"><![CDATA[
177 // AuthController / loginAction の中の処理
178 $result = $this->_auth->authenticate($adapter);
180 switch ($result->getCode()) {
182 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
183 /** ID が存在しない場合の処理 **/
186 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
190 case Zend_Auth_Result::SUCCESS:
195 /** その他の原因で失敗した場合の処理 **/
202 <sect2 id="zend.auth.introduction.persistence">
204 <title>ID の永続性</title>
207 認証情報 (パスワードなど) を含む認証を要求するのは便利なものですが、
208 リクエストごとにいちいち認証情報を引き回すのではなく、
209 認証済みの ID を保持し続けることも重要です。
213 <acronym>HTTP</acronym> はステートレスなプロトコルです。しかし、
214 クッキーやセッションといった技術によって、
216 複数リクエスト間でステート (状態) を保持し続けられるようになりました。
219 <sect3 id="zend.auth.introduction.persistence.default">
221 <title>PHP セッションにおけるデフォルトの持続性</title>
224 デフォルトでは、<classname>Zend_Auth</classname> は、
225 認証に成功した際の ID 情報を <acronym>PHP</acronym> のセッションを使用して保存します。
226 認証に成功すると、<methodname>Zend_Auth::authenticate()</methodname>
227 は認証結果を持続ストレージに保存します。何も指定しなければ、
228 <classname>Zend_Auth</classname> が使用するストレージクラスは
229 <classname>Zend_Auth_Storage_Session</classname> となります。これは
230 <link linkend="zend.session"><classname>Zend_Session</classname></link> を使用しています。
231 独自のクラスを使用するには、<classname>Zend_Auth_Storage_Interface</classname>
232 を実装したクラスのオブジェクトを <methodname>Zend_Auth::setStorage()</methodname>
238 もし ID が自動的に持続ストレージに保存されるのが気に入らない場合は、
239 <classname>Zend_Auth</classname> クラスをまるごと使用するのを控え、
244 <example id="zend.auth.introduction.persistence.default.example">
246 <title>セッション名前空間の変更</title>
249 <classname>Zend_Auth_Storage_Session</classname> は、セッション名前空間として
250 '<classname>Zend_Auth</classname>' を使用します。これを変更するには、別の値を
251 <classname>Zend_Auth_Storage_Session</classname> のコンストラクタで指定します。
252 この値が、内部で <classname>Zend_Session_Namespace</classname>
253 のコンストラクタに渡されます。これは認証を試みる前に行う必要があります。
254 なぜなら、<methodname>Zend_Auth::authenticate()</methodname>
258 <programlisting language="php"><![CDATA[
259 // Zend_Auth のシングルトンインスタンスへの参照を保存します
260 $auth = Zend_Auth::getInstance();
262 // 'Zend_Auth' のかわりに 'someNamespace' を使用します
263 $auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
266 * @todo 認証アダプタ $authAdapter を設定します
269 // 認証と結果の保存、そして成功時に ID を持続させます
270 $result = $auth->authenticate($authAdapter);
277 <sect3 id="zend.auth.introduction.persistence.custom">
279 <title>独自のストレージの実装</title>
282 <classname>Zend_Auth_Storage_Session</classname> とは異なる形式で、
283 ID を持続させたくなることもあるでしょう。そのような場合は、
284 <classname>Zend_Auth_Storage_Interface</classname> を実装したクラスのインスタンスを
285 <methodname>Zend_Auth::setStorage()</methodname> で設定します。
288 <example id="zend.auth.introduction.persistence.custom.example">
290 <title>独自のストレージクラスの使用法</title>
294 <classname>Zend_Auth_Storage_Session</classname> の代わりに使用するには、
295 <classname>Zend_Auth_Storage_Interface</classname> を実装します。
298 <programlisting language="php"><![CDATA[
299 class MyStorage implements Zend_Auth_Storage_Interface
302 * ストレージが空の場合にのみ true を返す
304 * @throws Zend_Auth_Storage_Exception 空かどうか判断できないとき
307 public function isEmpty()
319 * @throws Zend_Auth_Storage_Exception ストレージの中身を読み込めない場合
322 public function read()
330 * $contents をストレージに書き込む
332 * @param mixed $contents
333 * @throws Zend_Auth_Storage_Exception $contents をストレージに書き込めない場合
336 public function write($contents)
346 * @throws Zend_Auth_Storage_Exception ストレージの中身を消去できない場合
349 public function clear()
359 このストレージクラスを使用するには、認証クエリの前に
360 <methodname>Zend_Auth::setStorage()</methodname> を実行します。
363 <programlisting language="php"><![CDATA[
364 // Zend_Auth に、独自のストレージクラスを使うよう指示します
365 Zend_Auth::getInstance()->setStorage(new MyStorage());
368 * @todo 認証アダプタ $authAdapter を設定します
371 // 認証と結果の保存、そして成功時に ID を持続させます
372 $result = Zend_Auth::getInstance()->authenticate($authAdapter);
381 <sect2 id="zend.auth.introduction.using">
386 <classname>Zend_Auth</classname> の使用法には、次の二通りがあります。
392 間接的に <methodname>Zend_Auth::authenticate()</methodname> 経由で使用する
397 直接、アダプタの <methodname>authenticate()</methodname> メソッドを使用する
403 次の例は、<classname>Zend_Auth</classname> アダプタを間接的に
404 <classname>Zend_Auth</classname> クラスから使用するものです。
407 <programlisting language="php"><![CDATA[
408 // Zend_Auth のシングルトンインスタンスへの参照を取得します
409 $auth = Zend_Auth::getInstance();
412 $authAdapter = new MyAuthAdapter($username, $password);
415 $result = $auth->authenticate($authAdapter);
417 if (!$result->isValid()) {
418 // 認証に失敗したので、原因を表示します
419 foreach ($result->getMessages() as $message) {
423 // 認証に成功しました。ID ($username) がセッションに保存されます
424 // $result->getIdentity() === $auth->getIdentity()
425 // $result->getIdentity() === $username
430 上の例においてリクエスト内で認証が行われると、
431 認証に成功した際にその ID を取得するのは簡単なことです。
434 <programlisting language="php"><![CDATA[
435 $auth = Zend_Auth::getInstance();
436 if ($auth->hasIdentity()) {
438 $identity = $auth->getIdentity();
443 永続ストレージから認証 ID を削除するには、単純に
444 <methodname>clearIdentity()</methodname> メソッドを使用します。
445 これは、アプリケーションの "ログアウト" 処理を実装するためのものです。
448 <programlisting language="php"><![CDATA[
449 Zend_Auth::getInstance()->clearIdentity();
453 自動的に永続ストレージが用いられるのがまずい場合もあるでしょう。
454 そんな場合は、<classname>Zend_Auth</classname> クラスをバイパスして
456 アダプタクラスを直接使用するとは、アダプタオブジェクトの設定と準備を行い、
457 その <methodname>authenticate()</methodname> メソッドをコールするということです。
458 アダプタ固有の詳細情報については、各アダプタのドキュメントで説明します。
459 以下の例は、<classname>MyAuthAdapter</classname> を直接使用するものです。
462 <programlisting language="php"><![CDATA[
464 $authAdapter = new MyAuthAdapter($username, $password);
467 $result = $authAdapter->authenticate();
469 if (!$result->isValid()) {
470 // 認証に失敗したので、原因を表示します
471 foreach ($result->getMessages() as $message) {
476 // $result->getIdentity() === $username