[ZF-10089] Zend_Log
[zend.git] / documentation / manual / es / module_specs / Zend_Auth_Adapter_DbTable.xml
blob7b85c87437583bf848f96bb1bf2d8714c8e6f660
1 <?xml version="1.0" encoding="UTF-8"?>
2     <!-- EN-Revision: 17175 -->
3     <!-- Reviewed: no -->
4 <sect1 id="zend.auth.adapter.dbtable">
5     <title>Tabla de base de datos de autenticación</title>
6     <sect2 id="zend.auth.adapter.dbtable.introduction">
7         <title>Introducción</title>
8         <para>
9             <classname>Zend_Auth_Adapter_DbTable</classname>
10             proporciona la
11             capacidad de autenticar contra credenciales almacenadas en una tabla
12             de la
13             base de datos. Como
14             <classname>Zend_Auth_Adapter_DbTable</classname>
15             requiere una
16             instancia de
17             <classname>Zend_Db_Adapter_Abstract</classname>
18             que
19             será pasada a su constructor, cada instancia está vinculada a una
20             conexión concreta de
21             la base de datos. Se pueden establecer otras
22             opciones de configuración a través del
23             constructor y de métodos de
24             instancia:
25         </para>
26         <para>Las opciones de configuración disponibles incluyen:
27        </para>
29         <itemizedlist>
30             <listitem>
31                 <para>
32                     <emphasis>
33                         <property>tableName</property>
34                     </emphasis>
35                     : Nombre de tabla de
36                     la base de datos que contiene las credenciales de
37                     autenticación, y contra la cual se realiza la búsqueda
38                     de autenticación en la
39                     base de datos.
40                 </para>
41             </listitem>
42             <listitem>
43                 <para>
44                     <emphasis>
45                         <property>identityColumn</property>
46                     </emphasis>
47                     : Nombre de la
48                     columna de la tabla de la base de datos utilizada para
49                     representar
50                     la identidad. La columna identidad debe
51                     contar con valores únicos, tales como un
52                     apellido ó una
53                     dirección de e-mail.
54                 </para>
55             </listitem>
56             <listitem>
57                 <para>
58                     <emphasis>
59                         <property>credentialColumn</property>
60                     </emphasis>
61                     : Nombre de la
62                     columna de la tabla de la base de datos utilizada para
63                     representar
64                     la credencial. Conforme a un sistema de
65                     identidad simple y autenticación de
66                     contraseña, el valor
67                     de la credencial corresponde con la contraseña. Véase
68                     también la opción
69                     <property>credentialTreatment
70                     </property>
71                     .
72                 </para>
73             </listitem>
74             <listitem>
75                 <para>
76                     <emphasis>
77                         <property>credentialTreatment</property>
78                     </emphasis>
79                     : En muchos
80                     casos, contraseñas y otros datos son encriptados,
81                     mezclados, codificados, ocultados, desplazados o
82                     tratados de otra manera a través de alguna función o
83                     algoritmo. Al especificar una cadena de tratamiento
84                     parametrizada con este método, tal como
85                     <methodname>'MD5(?)'</methodname>
86                     o
87                     <methodname>'PASSWORD(?)'</methodname>
88                     , un
89                     desarrollador podría aplicar sentencias arbitrarias
90                     <acronym>SQL</acronym>
91                     sobre los datos credenciales de entrada. Ya que estas
92                     funciones son específicas de los
93                     <acronym>RDBMS</acronym>
94                     , debemos
95                     consultar el manual de la base de datos para comprobar
96                     la disponibilidad de tales funciones para su sistema de
97                     base de datos.
98                 </para>
99             </listitem>
100         </itemizedlist>
102         <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
103             <title>Uso Básico</title>
104             <para>
105                 Como se explicó en la introducción, el constructor
106                 <classname>Zend_Auth_Adapter_DbTable</classname>
107                 requiere
108                 una instancia de
109                 <classname>Zend_Db_Adapter_Abstract</classname>
110                 que sirve como conexión a la base de datos a la cual la
111                 instancia de autenticación
112                 está obligada a adaptarse. En primer
113                 lugar, la conexión de la base de datos debe ser
114                 creada.
115             </para>
116             <para>
117                 El siguiente código crea un adaptador para una base de datos
118                 en memoria , un esquema
119                 simple de la tabla, e inserta una fila
120                 contra la que se pueda realizar una consulta
121                 de autenticación
122                 posterior. Este ejemplo requiere que la extensión
123                 <acronym>PDO</acronym>
124                 SQLite
125                 esté disponible.
126             </para>
127             <programlisting language="php"><![CDATA[
128 // Crear una conexión en memoria de la bade de datos SQLite
129 $dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' =>
130                                                   ':memory:'));
132 // Construir mediante una consulta una simple tabla
133 $sqlCreate = 'CREATE TABLE [users] ('
134            . '[id] INTEGER  NOT NULL PRIMARY KEY, '
135            . '[username] VARCHAR(50) UNIQUE NOT NULL, '
136            . '[password] VARCHAR(32) NULL, '
137            . '[real_name] VARCHAR(150) NULL)';
139 // Crear las credenciales de autenticación de la tabla
140 $dbAdapter->query($sqlCreate);
142 // Construir una consulta para insertar una fila para que se pueda realizar la autenticación
143 $sqlInsert = "INSERT INTO users (username, password, real_name) "
144            . "VALUES ('my_username', 'my_password', 'My Real Name')";
146 // Insertar los datos
147 $dbAdapter->query($sqlInsert);
148 ]]></programlisting>
149             <para>
150                 Con la conexión de la base de datos y los datos de la tabla
151                 disponibles, podemos
152                 crear un instancia de
153                 <classname>Zend_Auth_Adapter_DbTable</classname>
154                 . Los
155                 valores de las opciones de configuración pueden ser pasados al
156                 constructor o
157                 pasados como parámetros a los métodos setter
158                 después de ser instanciados.
159             </para>
160             <programlisting language="php"><![CDATA[
161 // Configurar la instancia con los parámetros del constructor...
162 $authAdapter = new Zend_Auth_Adapter_DbTable(
163     $dbAdapter,
164     'users',
165     'username',
166     'password'
169 // ...o configurar la instancia con los métodos setter.
170 $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
172 $authAdapter
173     ->setTableName('users')
174     ->setIdentityColumn('username')
175     ->setCredentialColumn('password')
177 ]]></programlisting>
178             <para>
179                 En este punto, el adaptador de la instancia de autenticación
180                 está listo para aceptar
181                 consultas de autenticación. Con el fin
182                 de elaborar una consulta de autenticación, los
183                 valores de
184                 entrada de la credencial son pasados por el adaptador ates de
185                 llamar al
186                 método
187                 <methodname>authenticate()</methodname>
188                 :
189             </para>
190             <programlisting language="php"><![CDATA[
191 // Seleccionamos los valores de entrada de la credencial (e.g., de un formulario de acceso)
192 $authAdapter
193     ->setIdentity('my_username')
194     ->setCredential('my_password')
197 // Ejecutamos la consulta de autenticación, salvando los resultados
198 ]]></programlisting>
199             <para>
200                 Además de la disponibilidad del método
201                 <methodname>getIdentity()</methodname>
202                 sobre el objeto
203                 resultante de la autenticación,
204                 <classname>Zend_Auth_Adapter_DbTable</classname>
205                 también
206                 ayuda a recuperar la fila de al tabla sobre la autenticación
207                 realizada.
208             </para>
209             <programlisting language="php"><![CDATA[
210 // Imprimir la identidad
211 echo $result->getIdentity() . "\n\n";
213 // Imprimir la fila resultado
214 print_r($authAdapter->getResultRowObject());
216 /* Salida:
217 my_username
219 Array
221     [id] => 1
222     [username] => my_username
223     [password] => my_password
224     [real_name] => My Real Name
226 ]]></programlisting>
227             <para>Ya que la fila de la tabla contiene el valor de la
228                 credencial, es importante
229                 proteger los valores contra accesos no
230                 deseados.</para>
231         </example>
232     </sect2>
233     <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
234         <title>Advanced Usage: Manteniendo el resultado del Objeto
235             DbTable</title>
236         <para>
237             Por defecto,
238             <classname>Zend_Auth_Adapter_DbTable</classname>
239             devuelve la identidad proporcionada al objeto Auth en la
240             autenticación realizada. Otro de
241             los casos de uso, donde los
242             desarrolladores desean guardar para mantener el mecanismo de
243             almacenamiento de un objeto identidad
244             <classname>Zend_Auth</classname>
245             que contiene información útil,
246             se resuelve usando el método
247             <methodname>getResultRowObject()</methodname>
248             para devolver un
249             objeto
250             <emphasis>stdClass</emphasis>
251             . El siguiente fragmento de
252             código muestra su uso:
253         </para>
254         <programlisting language="php"><![CDATA[
255 // Autenticar con Zend_Auth_Adapter_DbTable
256 $result = $this->_auth->authenticate($adapter);
258 if ($result->isValid()) {
259     // Almacena la identidad como un objedo dónde solo username y
260     // real_name han sido devueltos
261     $storage = $this->_auth->getStorage();
262     $storage->write($adapter->getResultRowObject(array(
263         'username',
264         'real_name',
265     )));
267     // Almacena la identidad como un objeto dónde la columna contraseña ha
268     // sido omitida
269     $storage->write($adapter->getResultRowObject(
270         null,
271         'password'
272     ));
274     /* ... */
276 } else {
278     /* ... */
281 ]]></programlisting>
282     </sect2>
284     <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
285         <title>Ejemplo de Uso Avanzado</title>
286         <para>
287             Si bien el objetivo primordial de
288             <classname>Zend_Auth</classname>
289             (y, por consiguiente,
290             <classname>Zend_Auth_Adapter_DbTable</classname>
291             ) es
292             principalmente la
293             <emphasis>autenticación</emphasis>
294             y no la
295             <emphasis>autorización</emphasis>
296             , hay unos pocos casos y
297             problemas que se encuentran al límite entre cuales encajan
298             dentro
299             del dominio. Dependiendo de cómo haya decidido explicar su problema,
300             a veces tiene
301             sentido resolver lo que podría parecer un problema de
302             autorización dentro de un adaptador
303             de autenticación.
304         </para>
306         <para>
307             Con esa excepción fuera de lo común,
308             <classname>Zend_Auth_Adapter_DbTable</classname>
309             ha construido
310             mecanismos que pueden ser aprovechados para realizar controles
311             adicionales
312             en la autenticación a la vez que se resuelven algunos
313             problemas comunes de los usuarios.
314         </para>
316         <programlisting language="php"><![CDATA[
317 // El valor del campo status de una cuenta no es igual a "compromised"
318 $adapter = new Zend_Auth_Adapter_DbTable(
319     $db,
320     'users',
321     'username',
322     'password',
323     'MD5(?) AND status != "compromised"'
326 // El valor del campo active de una cuenta es igual a "TRUE"
327 $adapter = new Zend_Auth_Adapter_DbTable(
328     $db,
329     'users',
330     'username',
331     'password',
332     'MD5(?) AND active = "TRUE"'
333     ]]></programlisting>
335         <para>Otra idea puede ser la aplicación de un mecanismo de "salting".
336             "Salting" es un término
337             que se refiere a una técnica que puede
338             mejorar altamente la seguridad de su aplicación.
339             Se basa en la idea
340             de concatenar una cadena aleatoria a cada contraseña para evitar un
341             ataque de fuerza bruta sobre la base de datos usando los valores
342             hash de un diccionario
343             pre-calculado.</para>
345         <para>Por lo tanto, tenemos que modificar nuestra tabla para almacenar
346             nuestra cadena
347             mezclada:</para>
349         <programlisting language="php"><![CDATA[
350 $sqlAlter = "ALTER TABLE [users] "
351           . "ADD COLUMN [password_salt] "
352           . "AFTER [password]";
353 ]]></programlisting>
355         <para>Aquí hay una forma sencilla de generar una cadena mezclada por
356             cada usuario en el
357             momento del registro:</para>
359         <programlisting language="php"><![CDATA[
360 for ($i = 0; $i < 50; $i++) {
361     $dynamicSalt .= chr(rand(33, 126));
362 ]]></programlisting>
364         <para>Y ahora vamos a construir el adaptador:</para>
366         <programlisting language="php"><![CDATA[
367 $adapter = new Zend_Auth_Adapter_DbTable(
368     $db,
369     'users',
370     'username',
371     'password',
372     "MD5(CONCAT('"
373     . Zend_Registry::get('staticSalt')
374     . "', ?, password_salt))"
376 ]]></programlisting>
378         <note>
379             <para>
380                 Puede mejorar aún más la seguridad mediante el uso de un
381                 valor 'salt' estático
382                 fuertemente codificado en su aplicación.
383                 En el caso de que su base de datos se vea
384                 comprometida (por
385                 ejemplo, por un ataque de inyección
386                 <acronym>SQL</acronym>
387                 ), su servidor web está
388                 intacto y sus datos son inutilizable para el atacante.
389             </para>
390         </note>
392         <para>
393             Otra alternativa es utilizar el método
394             <methodname>getDbSelect()</methodname>
395             de
396             <classname>Zend_Auth_Adapter_DbTable</classname>
397             después de que el adaptador se ha
398             construido. Este método devolverá la instancia del
399             objeto
400             <classname>Zend_Db_Select</classname>
401             que se va a utilizar para completar la rutina de
402             authenticate(). Es importante señalar
403             que este método siempre
404             devuelve el mismo objeto, independientemente de si
405             <methodname>authenticate()</methodname>
406             ha
407             sido llamado o no. Este objeto
408             <emphasis>no tendrá</emphasis>
409             ninguna de las credenciales de identidad o información de como estos
410             valores son
411             colocados dentro del objeto seleccionado en
412             <methodname>authenticate()</methodname>
413             .
414         </para>
416         <para>
417             Un ejemplo de una situación en la que uno podría querer utilizar
418             el método
419             <methodname>getDbSelect()</methodname>
420             sería comprobar el estado de un usuario, en
421             otras palabras, ver si la cuenta del usuario
422             está habilitada.
423         </para>
425         <programlisting language="php"><![CDATA[
426 // Continuando con el ejemplo de arriba
427 $adapter = new Zend_Auth_Adapter_DbTable(
428     $db,
429     'users',
430     'username',
431     'password',
432     'MD5(?)'
435 // obtener el objeto select (por referencia)
436 $select = $adapter->getDbSelect();
437 $select->where('active = "TRUE"');
439 // authenticate, esto asegura que users.active = TRUE
440 $adapter->authenticate();
441 ]]></programlisting>
442     </sect2>
443 </sect1>