===== Seguridad. Autorización de acciones ===== Yii implementa dos métodos de autorización de acciones. Uno básico, válido para aplicaciones que únicamente necesiten controlar el acceso en función de si un usuario está logueado o no, o tiene un perfil determinado (administrador, usuario, etc...). En [[http://www.yiiframework.com/doc-2.0/guide-security-authorization.html|este enlace]] puedes consultar los detalles. Aquí explicaremos cómo utilizar el método sencillo (ACF), usando una propiedad del usuario logueado que indica el rol o roles asignados. Imaginemos que en nuestra aplicación tenemos dos roles de usuario: el de administrador, que tiene permisos para gestionar toda la aplicación y el de usuario que tiene limitados determinados accesos. Por ejemplo: el administrador puede crear, modificar, borrar y listar usuarios, pero un usuario normal solamente puede ver su ficha de usuario y modificarla. === Cambios en el Modelo === En el modelo usuario necesitamos un atributo **rol (o roles)**. Este atributo puede ser: * Un campo de la tabla usuarios, donde guardaremos, por ejemplo: A si es administrador o U si es usario normal * Una relación con otro modelos (roles), que me devuelve una lista de roles admitidos para el usuario En cualquiera de los dos casos, tenemos una propiedad roles (string o array) que me dice qué roles tiene el usuario. Por comodidad, crearemos un método llamado hasRole($rol) que devolverá true cuando el usuario tenga ese rol asignado: class Usuarios extends ActiveRecord { ... function hasRole($role){ return $this->rol==$role; //return in_array($this->roles,$role); Si es un array de roles } ... } Simplemente con esto, ya podemos utilizar en nuestras vistas y controladores el chequeo de un rol, ya que Yii::$app->user->identity se corresponde con el modelo del usuario logueado, y podemos llamar al método que acabamos de crear para verificar si el usuario tiene un rol asignado === Chequeo del rol en vistas === Por ejemplo, si queremos que un botón en una vista aparezca solamente para los administradores: user->identity->hasRole('A') echo Html::a('Anular Pedido',['pedidos/enviar','id'=>$id]); Tal como se explica en la guia de Yii, en el controlador definiremos el valor de 'access' en el método behaviors, asociándolo a la clase AccessControl, y haremos una entrada por cada filtro que queramos poner. === Autorización de acciones en los controladores === Tal como se explica en el documento del enlace de arriba, utilizaremos la propiedad matchCallBack de AccessControl, definida en el método behaviors. Por ejemplo, para que la acción create y delete deUsuarios únicamente la pueda ejecutar un administrador, pero la acción update la puedan ejecutar los usuarios que estén logueados y situación de alta (estado ='A') : class UsuariosController extends Controller { public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'only' => ['create','delete','update'], 'rules' => [ ['allow' => true, 'actions' => ['create', 'delete'], 'matchCallback' => function ($rule, $action) { return Yii::$app->user->identity->hasRole('A'); } ], ['allow' => true, 'actions' => ['update'], 'matchCallback' => function ($rule, $action) { return !Yii::$app->user->isGuest && Yii::$app->user->identity->estado=="A"; //Un usuario identificado y de alta } ], ], ], ]; } // ... } Es habitual que determinadas acciones solamente se puedan ejecutar en función del valor de determinadas propiedades del modelo. Por ejemplo: la acción update en el caso anterior es utilizable por un usuario, pero solamente para sí mismo. O un pedido solamente se puede borrar si no ha sido enviado. Este tipo de filtros los pondremos en la acción del controlador: class UsuariosController extends Controller { ... public function actionUpate($id) { $user=Yii::$app->user->identity; if(!$user->hasRole("A") && $id!=$user->id) //Si el usuario no es administrador solamente puede acceder a sus datos throw new UnauthorizedHttpException('Acceso no permitido'); ... } }