Gestión de Usuarios y perfiles en Yii
Por amunoz el Martes, 9 de Septiembre de 2014, 13:21 - Enlace permanente
Yii Framework viene con unos usuarios por defecto definidos en un array, para cambiar esto por usuarios definidos por base de datos es necesario realizar algunos cambios...
Para empezar necesitamos la tabla de base de datos, en este caso trabajaremos con MySQL:
CREATE TABLE `usuario` ( `id_usuario` int(11) NOT NULL AUTO_INCREMENT, `login` varchar(45) NOT NULL COMMENT 'Usuario', `clave` varchar(45) NOT NULL COMMENT 'Clave', `cod_tipo_usuario` varchar(5) DEFAULT NULL COMMENT 'Tipo de usuario', PRIMARY KEY (`id_usuario`), UNIQUE KEY `USER_UNIQUE` (`login`) );
En base a esta tabla creamos el modelo y el controlador y también las vistas.
En el fichero protected/components/UserIdentity.php están definidos los usuarios por defecto de la aplicación, dentro del método authenticate() . Este fichero define una clase que extiende de CUserIdentity, esta clase es la que el framework trae por defecto y tiene los atributos username y password.
Al hacer login, la aplicación por defecto llama al modelo del formulario de login (/protected/models/LoginForm.php) y desde la función login() se instancia un nuevo objeto de la clase UserIdentity al que se le pasan el usuario y contraseña introducidos en el formulario y posteriormente llama al método authenticate().
Por lo tanto en el método authenticate() de UserIdentity.php cambiaremos el array por nuestro modelo Usuario:
public function authenticate() { $usuario = new Usuario(); $usuario->login = $this->username; $usuario->clave = $this->password; $this->errorCode = $usuario->authenticate(); $this->setState('id_usuario', $usuario->id_usuario); $this->setState('cod_tipo_usuario', $usuario->cod_tipo_usuario); return !$this->errorCode; }
La explicación del código es sencilla:
- Creamos el modelo Usuario.
- Le pasamos los atributos de login y clave.
- Autenticamos.
- Obtenemos los datos.
- Devolvemos el resultado.
Podríamos autenticar en este mismo fichero, pero he preferido hacerlo desde el modelo de Usuario para tenerlo todo ahí.
Ahora cambiaremos el modelo de Usuario para hacer el login contra la tabla.
El método authenticate() tiene que devolver un código de error definido como constantes en UserIdentity
public function authenticate() { $errorCode = UserIdentity::ERROR_USERNAME_INVALID; $user = Usuario::model()->findByAttributes(array('login' => $this->login)); if ($user === null) { // No se ha encontrado el usuario $errorCode = UserIdentity::ERROR_USERNAME_INVALID; } // $user->clave se refiere a la columna "clave" de la base de datos else if (sha1($this->clave) !== $user->clave) { $errorCode = UserIdentity::ERROR_PASSWORD_INVALID; } else { // Correcto, establecer los atributos $this->id_usuario = $user->id_usuario; $this->cod_tipo_usuario = $user->cod_tipo_usuario; $errorCode = UserIdentity::ERROR_NONE; } return $errorCode; }
En el método primero se busca por el login, y luego se compara la cadena del hash SHA1 con lo guardado en base de datos, si es correcto se establecen los atributos que obtendremos en el método de UserIdentity mediante setState.
En este punto ya tendremos autenticación contra nuestra base de datos.
Para la información obtenida (id_usuario y cod_tipo_usuario) posteriormente en la aplicación crearemos un fichero en /protected/components/EWebUser.php. Este fichero tendrá una clase que extenderá de CWebUser y que recibirá los datos del setState de UserIdentity:
<?php class EWebUser extends CWebUser { private $_userTable = array ( 'AD'=>'Administrador', 'EM'=>'Empresa', ); protected $_model; function isAdmin() { return (Yii::app()->user->isGuest) ? false : $this->cod_tipo_usuario == 'AD'; } function isEmpresa() { return (Yii::app()->user->isGuest) ? false : $this->cod_tipo_usuario == 'EM'; } function getIdUsuario(){ return $this->id_usuario; } }
Para que la aplicación use esta nueva clase tendremos que modificar en el /protected/config/main.php añadiendo el elemento class:
// application components 'components'=>array( 'user'=>array( ... 'class'=>'application.components.EWebUser', ... ),
Por último, el uso de las funciones definidas en este fichero se hace de la siguiente manera:
Yii::app()->user->isAdmin(); Yii::app()->user->isEmpresa(); Yii::app()->user->getIdUsuario();
Source: http://www.yiiframework.com/wiki/474/implementing-a-flat-user-access-system/
Saludos!