Zend_Auth.xml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.auth.introduction">
  5. <title>Введение</title>
  6. <para>
  7. <classname>Zend_Auth</classname> предоставляет <acronym>API</acronym> для аутентификации и
  8. включает в себя конкретные адаптеры для общих случаев применения.
  9. </para>
  10. <para>
  11. Задачей <classname>Zend_Auth</classname> является <emphasis>аутентификация</emphasis>,
  12. но не <emphasis>авторизация</emphasis>. Аутентификацию в общих чертах можно характеризовать
  13. как процесс определения, действительно ли сущность является тем, чем она претендует быть
  14. (то есть идентификация), на основании некоторого набора учетных данных. Авторизация же -
  15. процесс определения того, можно ли предоставить сущности доступ или разрешить выполнить
  16. действие, и это полностью вне сферы компетенции <classname>Zend_Auth</classname>.
  17. Дополнительную информацию об авторизации и контроле доступа в Zend Framework смотрите в
  18. <link linkend="zend.acl"><classname>Zend_Acl</classname></link>.
  19. </para>
  20. <note>
  21. <para>
  22. Класс <classname>Zend_Auth</classname> реализует паттерн Синглтон - только один экзмепляр
  23. класса доступен – через статический метод <methodname>getInstance()</methodname>. Это
  24. означает, что ключевые слова <emphasis>new</emphasis> или <emphasis>clone</emphasis> не
  25. будут работать с классом <classname>Zend_Auth</classname>. Вместо них используйте
  26. <methodname>Zend_Auth::getInstance()</methodname>.
  27. </para>
  28. </note>
  29. <sect2 id="zend.auth.introduction.adapters">
  30. <title>Адаптеры</title>
  31. <para>
  32. Адаптер <classname>Zend_Auth</classname> используется дла аутентификации посредством
  33. определенного сервиса, такого как <acronym>LDAP</acronym>, <acronym>СУРБД</acronym> или
  34. файлового хранилища. Адаптеры могут значительно различаться, но некоторые основные черты
  35. характерны для всех. Например, все адаптеры <classname>Zend_Auth</classname> принимают
  36. учетные данные, выполненяют запрос к аутентификационному сервису и возвращают результат.
  37. </para>
  38. <para>
  39. Каждый адаптер <classname>Zend_Auth</classname> реализует
  40. <classname>Zend_Auth_Adapter_Interface</classname>. Этот интерфейс определяет лишь один
  41. метод: <methodname>authenticate()</methodname>, который должен быть реализовать для
  42. выполнения аутентификационного запроса. Адаптер должен быть настроен до вызова
  43. <methodname>authenticate()</methodname>, настройка включает в себя установку учетных
  44. данных(например, логин и пароль) и определение специфичных значений, таких как настройки
  45. подключения к базе данных для адаптера таблиц БД.
  46. </para>
  47. <para>
  48. Это пример адаптера, требующего установки логина и пароля для аутентификации. Прочие
  49. детали, например каким образом аутентификационный сервис запрашивается, были опущены для
  50. кратости:
  51. </para>
  52. <programlisting language="php"><![CDATA[
  53. class MyAuthAdapter implements Zend_Auth_Adapter_Interface
  54. {
  55. /**
  56. * Устанавливает логин и пароль для аутентификации
  57. *
  58. * @return void
  59. */
  60. public function __construct($username, $password)
  61. {
  62. // ...
  63. }
  64. /**
  65. * Выполняет попытку аутентификации
  66. *
  67. * @throws Zend_Auth_Adapter_Exception Если аутентификация не может быть выполнена
  68. * @return Zend_Auth_Result
  69. */
  70. public function authenticate()
  71. {
  72. // ...
  73. }
  74. }
  75. ]]></programlisting>
  76. <para>
  77. Как указано в докблоке, <methodname>authenticate()</methodname> должен вернуть экземпляр
  78. <classname>Zend_Auth_Result</classname> (или унаследованный от него). Если по какой либо
  79. причине выполнение аутентификации невозможно, <methodname>authenticate()</methodname>
  80. должен бросить исключение, происходящее от
  81. <classname>Zend_Auth_Adapter_Exception</classname>.
  82. </para>
  83. </sect2>
  84. <sect2 id="zend.auth.introduction.results">
  85. <title>Результат аутентификации</title>
  86. <para>
  87. Метод <methodname>authenticate()</methodname> адаптера <classname>Zend_Auth</classname>
  88. возвращает экзмепляр <classname>Zend_Auth_Result</classname> для представления
  89. результата попытки аутентификации. Объект <classname>Zend_Auth_Result</classname>
  90. заполняется адаптером при создании, и следующие четыре метода представляют его базовый
  91. набор операций:
  92. </para>
  93. <itemizedlist>
  94. <listitem>
  95. <para>
  96. <methodname>isValid()</methodname> - возвращает <constant>TRUE</constant> только
  97. в случае успешной попытки аутентификации.
  98. </para>
  99. </listitem>
  100. <listitem>
  101. <para>
  102. <methodname>getCode()</methodname> - возвращает значение одной из констант
  103. <classname>Zend_Auth_Result</classname> для обозначения успешности попытки или
  104. типа возникшей ошибки. Это может быть использовано в ситуации, когда разработчик
  105. хочет различать результаты попыток аутентификации. К примеру, он может вести
  106. детальную статистку всех попыток, либо выводить нестандартные сообщения для
  107. удобства пользователей. Но при этом стоит учитывать риски предоставления
  108. пользователям подробных сведений вместо стандартных сообщений о неудаче.
  109. Подробнее о возвращаемых значениях смотрите ниже.
  110. </para>
  111. </listitem>
  112. <listitem>
  113. <para>
  114. <methodname>getIdentity()</methodname> - возвращает идентификатор, полученный в
  115. результе аутентификации.
  116. </para>
  117. </listitem>
  118. <listitem>
  119. <para>
  120. <methodname>getMessages()</methodname> - возвращает массив сообщений о ошибках,
  121. возникших в процессе попытки аутентификации.
  122. </para>
  123. </listitem>
  124. </itemizedlist>
  125. <para>
  126. Разработчик может пожелать выполнять различные действия на основании результата
  127. аутентификации. Например, он может найти полезным блокировку аккаунтов после нескольких
  128. вводов неправильного пароля, пометку IP после слишком многих попыток аутентификации
  129. с несуществующими данными или вывод настраиваемых сообщений о результате аутентификации.
  130. Существуют следующие коды результата:
  131. </para>
  132. <programlisting language="php"><![CDATA[
  133. Zend_Auth_Result::SUCCESS
  134. Zend_Auth_Result::FAILURE
  135. Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
  136. Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
  137. Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
  138. Zend_Auth_Result::FAILURE_UNCATEGORIZED
  139. ]]></programlisting>
  140. <para>
  141. Этот пример показывает, как разработчик может различным образом обработать результат
  142. аутентификации, используя значение кода:
  143. </para>
  144. <programlisting language="php"><![CDATA[
  145. // в AuthController / loginAction
  146. $result = $this->_auth->authenticate($adapter);
  147. switch ($result->getCode()) {
  148. case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  149. /** Выполнить действия при несуществующем идентификаторе **/
  150. break;
  151. case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  152. /** Выполнить действия при некорректных учетных данных **/
  153. break;
  154. case Zend_Auth_Result::SUCCESS:
  155. /** Выполнить действия при успешной аутентификации **/
  156. break;
  157. default:
  158. /** Выполнить действия для остальных ошибок **/
  159. break;
  160. }
  161. ]]></programlisting>
  162. </sect2>
  163. <sect2 id="zend.auth.introduction.persistence">
  164. <title>Постоянное хранение идентификатора пользователя</title>
  165. <para>
  166. Аутентификация запроса, содержащего учетные данные, важна сама по себе, но также важно
  167. поддерживать сохранение идентификатора без необходимости передачи учетных данных с
  168. каждым запросом.
  169. </para>
  170. <para>
  171. Протокол <acronym>HTTP</acronym> не имеет состояний, однако были разработаны такие
  172. технологии как куки(cookies) и сессии для поддержки состояния на стороне сервера между
  173. несколькими запросами к веб приложению.
  174. </para>
  175. <sect3 id="zend.auth.introduction.persistence.default">
  176. <title>Сохранение идентификатора в сессии PHP, по умолчанию</title>
  177. <para>
  178. По умолчанию, <classname>Zend_Auth</classname> обеспечивает постоянное хранение
  179. идентификатора полученного в результате успешной попытки аутентификации в
  180. <acronym>PHP</acronym> сессии.
  181. </para>
  182. <para>
  183. При успешной попытке, <methodname>Zend_Auth::authenticate()</methodname> сохраняет
  184. идентификатор в постоянном хранилище. Если не настроено по другому,
  185. <classname>Zend_Auth</classname> использует класс хранилища
  186. <classname>Zend_Auth_Storage_Session</classname>, который в свою очередь использует
  187. <link linkend="zend.session"><classname>Zend_Session</classname></link>.
  188. Вместо него может быть использован пользовательский класс, для этого нужно
  189. передать <methodname>Zend_Auth::setStorage()</methodname> объект, реализующий
  190. <classname>Zend_Auth_Storage_Interface</classname>.
  191. </para>
  192. <note>
  193. <para>
  194. Если автоматическое сохранение идентификатора не подходит в каком-либо
  195. конкретном случае, тогда разработчику следует отказаться от использования класса
  196. <classname>Zend_Auth</classname> и использовать адаптер напрямую.
  197. </para>
  198. </note>
  199. <example id="zend.auth.introduction.persistence.default.example">
  200. <title>Изменение пространства имен в сессии</title>
  201. <para>
  202. <classname>Zend_Auth_Storage_Session</classname> использует пространство имен
  203. '<classname>Zend_Auth</classname>'. Оно может быть переопределено передачей
  204. другого значения конструктору <classname>Zend_Auth_Storage_Session</classname>,
  205. которое будет дальше передано конструктору
  206. <classname>Zend_Session_Namespace</classname>. Это нужно сделать до того, как
  207. будет произведена попытка аутентификации, так как
  208. <methodname>Zend_Auth::authenticate()</methodname> выполняет автоматическое
  209. сохранение идентификатора.
  210. </para>
  211. <programlisting language="php"><![CDATA[
  212. // Получение синглтон экземпляра Zend_Auth
  213. $auth = Zend_Auth::getInstance();
  214. // Установка 'someNamespace' вместо 'Zend_Auth'
  215. $auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
  216. /**
  217. * @todo подготовка адаптера, $authAdapter
  218. */
  219. // Аутентификация, сохранение результата, и хранение идентификатора
  220. // при успехе.
  221. $result = $auth->authenticate($authAdapter);
  222. ]]></programlisting>
  223. </example>
  224. </sect3>
  225. <sect3 id="zend.auth.introduction.persistence.custom">
  226. <title>Реализация пользовательского хранилища</title>
  227. <para>
  228. Иногда разработчику может понадобиться использовать иной механизм хранения
  229. идентификаторов, нежели предоставляется в
  230. <classname>Zend_Auth_Storage_Session</classname>. В том случае он может реализовать
  231. <classname>Zend_Auth_Storage_Interface</classname> и передать экземпляр
  232. методу <methodname>Zend_Auth::setStorage()</methodname>.
  233. </para>
  234. <example id="zend.auth.introduction.persistence.custom.example">
  235. <title>Использование пользовательского хранилища</title>
  236. <para>
  237. Для того, чтобы использовать иной класс хранилища пользовательских
  238. идентификаторов, нежели <classname>Zend_Auth_Storage_Session</classname>,
  239. разработчик реализует <classname>Zend_Auth_Storage_Interface</classname>:
  240. </para>
  241. <programlisting language="php"><![CDATA[
  242. class MyStorage implements Zend_Auth_Storage_Interface
  243. {
  244. /**
  245. * Возвращает true, если хранилище пусто
  246. *
  247. * @throws Zend_Auth_Storage_Exception В случае если невозможно
  248. * определить, пусто ли
  249. * хранилище
  250. * @return boolean
  251. */
  252. public function isEmpty()
  253. {
  254. /**
  255. * @todo реализация
  256. */
  257. }
  258. /**
  259. * Возвращает содержимое хранилища
  260. *
  261. * Поведение неопределено, когда хранилище пусто.
  262. *
  263. * @throws Zend_Auth_Storage_Exception Если получение содержимого
  264. * хранилища невозможно
  265. * @return mixed
  266. */
  267. public function read()
  268. {
  269. /**
  270. * @todo реализация
  271. */
  272. }
  273. /**
  274. * Записывает $contents в хранилище
  275. *
  276. * @param mixed $contents
  277. * @throws Zend_Auth_Storage_Exception Если запись содержимого в
  278. * хранилище невозможна
  279. * @return void
  280. */
  281. public function write($contents)
  282. {
  283. /**
  284. * @todo реализация
  285. */
  286. }
  287. /**
  288. * Очищает содержмое хранилища
  289. *
  290. * @throws Zend_Auth_Storage_Exception Если очищение хранилища
  291. * невозможно
  292. * @return void
  293. */
  294. public function clear()
  295. {
  296. /**
  297. * @todo реализация
  298. */
  299. }
  300. }
  301. ]]></programlisting>
  302. <para>
  303. Для использования этого класса, <methodname>Zend_Auth::setStorage()</methodname>
  304. вызывается до выполнения попытки авторизации:
  305. </para>
  306. <programlisting language="php"><![CDATA[
  307. // Сказать Zend_Auth использовать пользовательский класс хранилища
  308. Zend_Auth::getInstance()->setStorage(new MyStorage());
  309. /**
  310. * @todo подготовка адаптера, $authAdapter
  311. */
  312. // Аутентификация, сохранение результата, и хранение идентификатора
  313. // при успехе.
  314. $result = Zend_Auth::getInstance()->authenticate($authAdapter);
  315. ]]></programlisting>
  316. </example>
  317. </sect3>
  318. </sect2>
  319. <sect2 id="zend.auth.introduction.using">
  320. <title>Использование</title>
  321. <para>
  322. Существует два пути использования адаптеров <classname>Zend_Auth</classname>:
  323. </para>
  324. <orderedlist>
  325. <listitem>
  326. <para>
  327. непрямое, через <methodname>Zend_Auth::authenticate()</methodname>
  328. </para>
  329. </listitem>
  330. <listitem>
  331. <para>
  332. прямое, через метод адаптера <methodname>authenticate()</methodname>
  333. </para>
  334. </listitem>
  335. </orderedlist>
  336. <para>
  337. Следующий пример показывает, как использовать адаптер <classname>Zend_Auth</classname>
  338. через класс <classname>Zend_Auth</classname>:
  339. </para>
  340. <programlisting language="php"><![CDATA[
  341. // Получение синглтон экземпляра Zend_Auth
  342. $auth = Zend_Auth::getInstance();
  343. // Установка адаптера
  344. $authAdapter = new MyAuthAdapter($username, $password);
  345. // Попытка аутентификации, сохранение результата
  346. $result = $auth->authenticate($authAdapter);
  347. if (!$result->isValid()) {
  348. // Попытка неуспешна; вывести сообщения об ошибках
  349. foreach ($result->getMessages() as $message) {
  350. echo "$message\n";
  351. }
  352. } else {
  353. // Попытка успешна; идентификатор ($username) сохранен
  354. // в сессии
  355. // $result->getIdentity() === $auth->getIdentity()
  356. // $result->getIdentity() === $username
  357. }
  358. ]]></programlisting>
  359. <para>
  360. После того как попытка аутентификации была произведена, как показано в примере выше,
  361. теперь нужно только проверить, существует ли аутентифицированный идентификатор:
  362. </para>
  363. <programlisting language="php"><![CDATA[
  364. $auth = Zend_Auth::getInstance();
  365. if ($auth->hasIdentity()) {
  366. // Идентификатор существует; получить его
  367. $identity = $auth->getIdentity();
  368. }
  369. ]]></programlisting>
  370. <para>
  371. Для удаления идентификатора из постоянного хранилища, просто используйте метод
  372. <methodname>clearIdentity()</methodname>. Обычно это используется для реализации
  373. действия "Выйти":
  374. </para>
  375. <programlisting language="php"><![CDATA[
  376. Zend_Auth::getInstance()->clearIdentity();
  377. ]]></programlisting>
  378. <para>
  379. Когда автоматическое использование постоянного хранилища не подходит, разработчик
  380. может просто обойти <classname>Zend_Auth</classname> и использовать класс адаптера
  381. напрямую. Прямое использование адаптера включает в себя настройку, подготовку объекта
  382. адаптера и последующий вызов его метода, <methodname>authenticate()</methodname>.
  383. Специфичные для адаптера детали обсуждаются в документации этого адаптера. Следующий
  384. пример напрямую использует <classname>MyAuthAdapter</classname>:
  385. </para>
  386. <programlisting language="php"><![CDATA[
  387. // Подготовка адаптера
  388. $authAdapter = new MyAuthAdapter($username, $password);
  389. // Попытка аутентификации, сохранение результата
  390. $result = $authAdapter->authenticate();
  391. if (!$result->isValid()) {
  392. // Попытка неуспешна; вывести сообщения об ошибках
  393. foreach ($result->getMessages() as $message) {
  394. echo "$message\n";
  395. }
  396. } else {
  397. // Попытка успешна;
  398. // $result->getIdentity() === $username
  399. }
  400. ]]></programlisting>
  401. </sect2>
  402. </sect1>
  403. <!--
  404. vim:se ts=4 sw=4 et:
  405. -->