1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 17175 -->
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>
9 <classname>Zend_Auth_Adapter_DbTable</classname>
11 capacidad de autenticar contra credenciales almacenadas en una tabla
14 <classname>Zend_Auth_Adapter_DbTable</classname>
17 <classname>Zend_Db_Adapter_Abstract</classname>
19 será pasada a su constructor, cada instancia está vinculada a una
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
26 <para>Las opciones de configuración disponibles incluyen:
33 <property>tableName</property>
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
45 <property>identityColumn</property>
48 columna de la tabla de la base de datos utilizada para
50 la identidad. La columna identidad debe
51 contar con valores únicos, tales como un
59 <property>credentialColumn</property>
62 columna de la tabla de la base de datos utilizada para
64 la credencial. Conforme a un sistema de
65 identidad simple y autenticación de
67 de la credencial corresponde con la contraseña. Véase
69 <property>credentialTreatment
77 <property>credentialTreatment</property>
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>
87 <methodname>'PASSWORD(?)'</methodname>
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>
95 consultar el manual de la base de datos para comprobar
96 la disponibilidad de tales funciones para su sistema de
102 <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
103 <title>Uso Básico</title>
105 Como se explicó en la introducción, el constructor
106 <classname>Zend_Auth_Adapter_DbTable</classname>
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
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
122 posterior. Este ejemplo requiere que la extensión
123 <acronym>PDO</acronym>
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' =>
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);
150 Con la conexión de la base de datos y los datos de la tabla
152 crear un instancia de
153 <classname>Zend_Auth_Adapter_DbTable</classname>
155 valores de las opciones de configuración pueden ser pasados al
157 pasados como parámetros a los métodos setter
158 después de ser instanciados.
160 <programlisting language="php"><![CDATA[
161 // Configurar la instancia con los parámetros del constructor...
162 $authAdapter = new Zend_Auth_Adapter_DbTable(
169 // ...o configurar la instancia con los métodos setter.
170 $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
173 ->setTableName('users')
174 ->setIdentityColumn('username')
175 ->setCredentialColumn('password')
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
184 entrada de la credencial son pasados por el adaptador ates de
187 <methodname>authenticate()</methodname>
190 <programlisting language="php"><![CDATA[
191 // Seleccionamos los valores de entrada de la credencial (e.g., de un formulario de acceso)
193 ->setIdentity('my_username')
194 ->setCredential('my_password')
197 // Ejecutamos la consulta de autenticación, salvando los resultados
200 Además de la disponibilidad del método
201 <methodname>getIdentity()</methodname>
203 resultante de la autenticación,
204 <classname>Zend_Auth_Adapter_DbTable</classname>
206 ayuda a recuperar la fila de al tabla sobre la autenticación
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());
222 [username] => my_username
223 [password] => my_password
224 [real_name] => My Real Name
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
233 <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
234 <title>Advanced Usage: Manteniendo el resultado del Objeto
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>
250 <emphasis>stdClass</emphasis>
251 . El siguiente fragmento de
252 código muestra su uso:
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(
267 // Almacena la identidad como un objeto dónde la columna contraseña ha
269 $storage->write($adapter->getResultRowObject(
284 <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
285 <title>Ejemplo de Uso Avanzado</title>
287 Si bien el objetivo primordial de
288 <classname>Zend_Auth</classname>
289 (y, por consiguiente,
290 <classname>Zend_Auth_Adapter_DbTable</classname>
293 <emphasis>autenticación</emphasis>
295 <emphasis>autorización</emphasis>
296 , hay unos pocos casos y
297 problemas que se encuentran al límite entre cuales encajan
299 del dominio. Dependiendo de cómo haya decidido explicar su problema,
301 sentido resolver lo que podría parecer un problema de
302 autorización dentro de un adaptador
307 Con esa excepción fuera de lo común,
308 <classname>Zend_Auth_Adapter_DbTable</classname>
310 mecanismos que pueden ser aprovechados para realizar controles
312 en la autenticación a la vez que se resuelven algunos
313 problemas comunes de los usuarios.
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(
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(
332 'MD5(?) AND active = "TRUE"'
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.
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
349 <programlisting language="php"><![CDATA[
350 $sqlAlter = "ALTER TABLE [users] "
351 . "ADD COLUMN [password_salt] "
352 . "AFTER [password]";
355 <para>Aquí hay una forma sencilla de generar una cadena mezclada por
357 momento del registro:</para>
359 <programlisting language="php"><![CDATA[
360 for ($i = 0; $i < 50; $i++) {
361 $dynamicSalt .= chr(rand(33, 126));
364 <para>Y ahora vamos a construir el adaptador:</para>
366 <programlisting language="php"><![CDATA[
367 $adapter = new Zend_Auth_Adapter_DbTable(
373 . Zend_Registry::get('staticSalt')
374 . "', ?, password_salt))"
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
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.
393 Otra alternativa es utilizar el método
394 <methodname>getDbSelect()</methodname>
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
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>
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
411 colocados dentro del objeto seleccionado en
412 <methodname>authenticate()</methodname>
417 Un ejemplo de una situación en la que uno podría querer utilizar
419 <methodname>getDbSelect()</methodname>
420 sería comprobar el estado de un usuario, en
421 otras palabras, ver si la cuenta del usuario
425 <programlisting language="php"><![CDATA[
426 // Continuando con el ejemplo de arriba
427 $adapter = new Zend_Auth_Adapter_DbTable(
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();