Usuarios y Sessiones en Yii
Buenas tardes a todos
Para ir un poco mas adelante en la construcción de un sitio web con Yii Framework nos encontramos con un tema básico en el desarrollo de cualquier sistema, la implementación de un sistema de logueo, usuarios, roles y permisos para diferentes acciones en el sistema.
Comenzando por explicar como tiene Yii configurado en su sistema base el logueo, nos encontramos con una acción en el controller “site/login” en la cual recibe la información de un formulario con usuario y contraseña.
public function actionLogin() { $model = new LoginForm; // if it is ajax validation request if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') { echo CActiveForm::validate($model); Yii::app()->end(); } // collect user input data if (isset($_POST['LoginForm'])) { $model->attributes = $_POST['LoginForm']; // validate user input and redirect to the previous page if valid if ($model->validate() && $model->login()) $this->redirect(array("perfil")); } // display the login form $this->render('login', array('model' => $model)); }
Esta acción a menos que tengamos algún requerimiento muy específico no debe cambiar, ya que solo nos permite desplegar el formulario y cuando ingresa la información mandarla a validar, a donde? pues esa es una pregunta importante.
En “protected/components/UserIdentity” nos encontramos con una función llamada authenticate, que por default valida sobre un Array, que contiene los usuarios admin y demo, y que sirven en la forma más sencilla de nuestro sistema, pero que puede ser sustituida por:
public function authenticate() { $registro = Usuario::model()->findByAttributes(array('email' => $this->username)); if ($registro === null) { $this->errorCode = self::ERROR_USERNAME_INVALID; } else if ($registro->password === crypt($this->password,$registro->salt)) {// $this->setState('id_usuario', $registro->id); $this->setState('id_rol', $registro->id_rol); $this->errorCode = self::ERROR_NONE; } else { $this->errorCode = self::ERROR_PASSWORD_INVALID; } return !$this->errorCode; }
El código anterior consulta nuestra base de datos buscando el usuario con el que coincida el correo que fue ingresado en el formulario de login, una vez encontrado, si existe, compara la contraseña almacenada en la base con la que fue enviado por el usuario, utilizando el mismo método de cifrado que se utilizó para almacenarla al principio.
Una vez comparado, y si no manda error, se declaran las variables de sesión que pudiéramos utilizar en el sistema para identificar a este usuario. Se pueden definir tantas variables como sea necesario, recordando que si se agrega una nueva variable o modifica la información, esta se tomará en cuanta cuando se vuelvan a loguear.
Estas variables podrán ser utilizadas a lo largo de la sesión del usuario utilizando las variables con formato:
Yii::app()->user->id_usuario;
Una buena practica es utilizar primero un “isset” para ver si el usuario de verdad tiene sesión, de lo contrario, el sistema arrojara un error al no encontrar dicha variable.
En cuanto a los roles en las acciones, los controladores generados con crud, traen por default el access rules, que define quien si y quien no, pasa a las acciones correspondientes del controlador:
public function accessRules() { return array( array('allow', // allow all user perform 'index' and 'view' actions 'actions' => array('index', 'view'), 'users' => array('*'), ), array('allow', // allow authenticated user to perform 'create' and 'update' actions 'actions' => array('create', 'update'), 'users' => array('@'), ), array('allow', // allow admin user to perform 'admin' and 'delete' actions 'actions' => array('admin', 'delete'), 'users' => array('admin'), ), array('deny', // deny all users 'users' => array('*'), ), ); }
Como podemos ver, tenemos cuatro escenarios:
En el primero, permitimos a todos los usuarios(*) entrar a la accion index y view
En el segundo, permitimos a todos los usuarios que tengan sesión iniciada(@) entrar a la acción create y update
En el tercero, permitimos a todos los usuarios que tengan sesión iniciada y que su usuario sea admin(admin) entrar a la acción admin y delete
En el cuarto, Negamos cualquier acción que no haya sido definida antes
Pero como esto no aplica para todos los casos, sino que podemos manejar roles, podríamos poner una regla como la siguiente:
array('allow', 'actions' => array('create', 'update'), 'users' => array('@'), 'expression' => 'Yii::app()->user->id_rol==1 || Yii::app()->user->id_rol==3', ),
Con esta regla, permitimos a todos los usuarios con sesión y que cuenten con un rol de usuario 1 o 2 a que ejecuten la acción create y update.
Existen otra formas de llevar a cabo acciones, permisos y roles, aunque esta puede adaptarse a las necesidades de tu proyecto, espero les sea útil
Felices Códigos