Cómo instalar RBAC


Cómo instalar RBAC

En el presente tutorial se mostrará cómo instalar y poner a operar la gestión de acceso el RBAC.

1.- Introducción 

Yii provee dos métodos de autorización:  RBAC por sus siglas en inglés (Rol Based Access Control) y ACF (Access Control Filter) .

2.- Instalación y configuración


Agregar la siguiente linea en el composer.json


"mdmsoft/yii2-admin": "~2.0"

Y ejecutamos el comando en la ruta raiz


composer update

Ahora tenemos que agregar la siguientes lineas, que están en negritas dentro del el archivo de configuración de la aplicación consola, que normalmente en la plantilla básica está en la ruta: "/config/console.php" y en la plantilla avanzada en "console/config/main.php".

Para mayor información sobre aplicaciones de consola en Yii puedes consultar este artículo sobre aplicaciones de consola en Yii. 


'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
        ],
       ....
        'log' => [
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
    ],

Este cambio permite que se pueda correr la migración que sigue a continuación.

Para saber más sobre las migraciones puedes consultar este artículo sobre migraciones

Posicionarse en la raíz del sitio y ejecutar el siguiente comando que es una migración. 

yii migrate --migrationPath=@yii/rbac/migrations

Deberá se salir algo así.


Con esta migración se crean las tablas que son utilizadas en el modulo


Para poder usar un administrador web es necesario agrear lo siguiente en el archivo de configuración de nuestra aplicación web.

Para la plantilla básica el archivo de configuración normalmente se encuentra en:  

/config/web.php 

Para la plantilla avanzada:

/backend/config/main.php 

Identifica en tu archivo de configuración la sección de "modules" y agrega la siguiente clase como lo muestra en el ejemplo que está en negritas. 

Identifica la sección de "components" y agrega las líneas que a continuación se muestran en negritas.



   // Sección de 'modules'

    'modules' => [
        'admin' => [
            'class' => 'mdm\admin\Module',
        ]

        ...
    ],

// Sección de 'components'
    ...
    'components' => [
        ...
        'authManager' => [
            'class' => 'yii\rbac\PhpManager', // or use 'yii\rbac\DbManager'
        ]

    ],

.......
// Sección raíz de configuración


    'as access' => [
        'class' => 'mdm\admin\components\AccessControl',
        'allowActions' => [
            'site/*',
            'admin/*',
            'some-controller/some-action',
            // The actions listed here will be allowed to everyone including guests.
            // So, 'admin/*' should not appear here in the production, of course.
            // But in the earlier stages of your development, you may probably want to
            // add a lot of actions here until you finally completed setting up rbac,
            // otherwise you may not even take a first step.
        ]

    ],





2.1 Rutas para entrar al administrador 

Por default para entrar a cada una de las rutas debes acceder a estas urls. Considerando que "path/to/" es la ruta de tu proyecto.


http://localhost/path/to/index.php?r=admin
http://localhost/path/to/index.php?r=admin/route
http://localhost/path/to/index.php?r=admin/permission
http://localhost/path/to/index.php?r=admin/menu
http://localhost/path/to/index.php?r=admin/role
http://localhost/path/to/index.php?r=admin/assignment
http://localhost/path/to/index.php?r=admin/user


Con esto aparecerá una ventana como la siguiente:


Ejemplo en una plantilla avanzada.


2.2 Agregar menú de navegación


De manera opcional se puede agregar el menú con el siguiente comando.


yii migrate --migrationPath=@mdm/admin/migrations




Esto crea una tabla llamada menú, pero para que se pueda ver se tiene que hacer una configuración extra más.

Dentro de tu archivo de configuración:

Para la plantilla básica el archivo de configuración normalmente se encuentra en:  

/config/web.php 

Para la plantilla avanzada:

/backend/config/main.php 


    'modules' => [
        'admin' => [
            ...
            'layout' => 'left-menu', // por defaults es null, cuando no deseas usar el menú 
                                    // Otros valores opcionales son 'right-menu' and 'top-menu' 
        ],
        ...
    ],


Con este cambio debería lucir así: 



Nota importante: 

Si navega por el menú notará que al entrar a la opción de "Usuarios" aparecerá el siguiente error, el cual es normal por que aun no tiene configurado un usuario activo. 






3.- Crear tu propio modelo de Usuarios

Hasta este momento solo cuentas con los usuarios que vienen por default en el template, que son los de: admin/admin y demo/demo los cuales puedes loguearte en el link de tu sitio "tusitio/web/site/login" pero estos no te servirán para lo que realmente deseas que es tener un control de usuarios y accesos, por este motivo yo te recomiendo que crees tu propio modelo de usuarios, para esto sigue los siguientes pasos.

3.1 Creando tabla de usuarios


Debes crear una tabla de usuarios, en este caso contiene los elementos básicos para comenzar. 

CREATE TABLE `tiendas`.`usuario` ( `id` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(255) NOT NULL , `names` VARCHAR(255) NOT NULL , `password` VARCHAR(255) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB; 

3.2 Programación de crud para tabla de usuarios

Una vez que tengas tu tabla en tu base de datos crea el CRUD correspondiente utilizando el Gii de Yii.

Recuerda que una vez que configuras el RBAC tendrás que agregar los permisos necesarios para tener acceso a "gii" por lo tanto debes agregar la siguiente línea en tu archivo de configuración "web".

Para plantilla básica utiliza el archivo:

/config/web.php 

Para la plantilla avanzada:

/backend/config/main.php 

Identifica la sección de código que dice "as access" si no la tienes configurada la puedes agregar. 

Agrega los siguientes tres items.

                'site/login',
                'site/logout',
                 'gii/*', 

Esta linea 'site/login', es para que puedas loguearte.

Esta linea 'site/logout', es para que puedas salir de la sesión. 

Y esta  'gii/*',  es para dar permiso de utilizar el gii y a todas sus subcarpetas,

        'as access' => [
            'class' => 'mdm\admin\components\AccessControl',
            'allowActions' => [
                'site/login',
                'site/logout',
                'admin/*',
                'gii/*',
                //'some-controller/some-action',
                // The actions listed here will be allowed to everyone including guests.
                // So, 'admin/*' should not appear here in the production, of course.
                // But in the earlier stages of your development, you may probably want to
                // add a lot of actions here until you finally completed setting up rbac,
                // otherwise you may not even take a first step.
            ]
        ],    

Nota importante: Si deseas restringir el uso del sitio debes comentar la siguiente linea:

'site/*', 

La cual indica que que puedes tener acceso a todo el sitio. 

Una vez que estés dentro de gii, crear el CRUD completo como se hacer normalmente cualquier otro.

Ya que tienes creado tu CRUD deberás agregar la programación necesaria para que cada vez que dentro de tus sistema crees un nuevo usuario dicho usuario se le agregue el rol correspondiente. 

Antes de poder realizar esto debes de agregar de manera temporal el acceso a todo el módulo de usuarios para poder probar, eso lo haces en el archivo de configuración agregado la siguiente ruta: 'usuario/*' dentro del arreglo como lo muestra el siguiente ejemplo:



        'as access' => [
            'class' => 'mdm\admin\components\AccessControl',
            'allowActions' => [
                'site/login',
                'site/logout',
                'admin/*',
                'gii/*',
                'usuario/*'
                //'some-controller/some-action',
                // The actions listed here will be allowed to everyone including guests.
                // So, 'admin/*' should not appear here in the production, of course.
                // But in the earlier stages of your development, you may probably want to
                // add a lot of actions here until you finally completed setting up rbac,
                // otherwise you may not even take a first step.
            ]
        ],    


3.3 Configurando la aplicación 

3.3.1 Cambiando  'authManager'  para utilizar Base de Datos

Para que podamos trabajar en conjunto con el manejo de usuarios desde base de datos con una tabla de usuarios es necesario cambiar la configuración de 'authManager', para esto debe identificar la siguiente línea en la sección de componentes y cambiarla:

 de 

'yii\rbac\PhpManager' 

 'yii\rbac\DbManager',

Con esto estamos diciendo que deseamos usar la configuración de usuarios por base de datos.


// Sección de 'components'
    ...
    'components' => [
        ...
        'authManager' => [
            'class' => 
'yii\rbac\DbManager'
        ]

    ],



3.3.2 Cambiando  'identityClass' en archivo de configuración

Debe identificar el arreglo que dice 'user' y modificar la siguiente línea.

'identityClass' => 'app\models\User',

por:

'identityClass' => 'app\models\Usuario',

Esto es por que estamos usando nuestro modelo que programamos llamado "Usuario"


// Sección de 'user'

        'user' => [
            'identityClass' => 'app\models\Usuario',
            'enableAutoLogin' => true,
        ],


3.4 Modificando el archivo 'LoginForm.php' 

Modificamos el archivo que viene por default llamado "/models/LoginForm.php".

El código origina es:

    public function login()
    {
        if ($this->validate()) {
            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
        }
        return false;
    }


Cambiarlo por:


    public function login()
    {
        
        $usuario = $this->getUser(); // Se agrega esta linea
        if ($this->validate()) {
            if($usuario){ // Se agrega este if 
                return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
            }                                    
        }
        return false;
    }


También debemos modificar el método llamado:  getUser()

Código original:


  
    public function getUser()
    {
        if ($this->_user === false) {
            $this->_user = User::findByUsername($this->username);
        }

        return $this->_user;
    }
     


Cambiamos el nombre del modelo que se manda a llamar por default a "Usuario" que es el que hemos creado, observe que el campo "username" no es necesario cambiarlo por que se llama igual.

    
    public function getUser()
    {
        if ($this->_user === false) {
           $this->_user = Usuario::findByUsername($this->username); // Cambiar por modelo de usuario creado
        }

        return $this->_user;
    }



3.5 Modificando el archivo de modelo 'Usuario.php' 

Los siguientes cambios son para adecuar nuestro modelo personalizado y que pueda ser utilizado para el login en conjunto con el RBAC.

Identifique el archivo /model/Usuario.php


Cambiar la linea que define la clase:

  
 class Usuario extends \yii\db\ActiveRecord
{
  ......
}



Y agregue lo siguiente "implements \yii\web\IdentityInterface"

  
class Usuario extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
  ......
}


Esto hará que se tengan que implementar algunos métodos que se heredan de "\yii\web\IdentityInterface" por consiguiente deberá de hacer los siguientes cambios: 

Agregar los siguientes métodos en el modelo Usuario.php:

  
     //Este lo pide pero lo dejamos como null por que no lo usamos por el momento
    public function getAuthKey() {
        return null;
       //return $this->auth_key;
    }    
    
    // interface
    public function validateAuthKey($authKey) {
        return $this->getAuthKey() == $authKey;
    }
    
    // interface
    public static function findIdentityByAccessToken($token, $type = null) {
        throw new \yii\base\NotSupportedException("'findIdentityByAccessToken' is not implemented");
    }
    
    /* Identity Interface */
    public function getId(){
        return $this->id;
    }
        
    public static function findIdentity($id) {
        return static::findOne(['id' => $id]);
    }
    
   // Utilizamos el mismo nombre de método que definimos como el nombre de usuario
    public static function findByUserName($username) {
        return static::findOne(['username' => $username]);
    }
    
    public function validatePassword($password) {
        return Yii::$app->security->validatePassword($password, $this->password);
    }



3.6 Modificando el create del Modelo 'Usuario.php'

3.6.1 Agrega el primer Rol de administrador

Tendrás que asignar el primer rol, para esto deberás entrar a la ruta de tu proyecto: 

'/web/admin/role

Aparecerá la siguient pantalla donde tendras que agregar un nuevo rol dando clic en el botón "Create Rol"


y agregar un primer rol que se llame 'administrador'.


3.6.2 Agrega en el controller de create la asignación del primer ROL

En esta parte vas a ver cómo vincular a un usuario con un ROL.

Ahora que has creado tu CRUD deberás de entrar a la url: 


Veras un listado de usuarios vacio, vamos a modificar primero el controller create para poder crear nuevos usuarios del sistema.

Para esto deberás modificar el controller que hemos creado llamado 'UsuarioController.php' utilizando el siguiente código en el controller 'create':


    public function actionCreate() {
        $model = new Usuario();

        if ($model->load(Yii::$app->request->post())) {

            $hash =  Yii::$app->security->generatePasswordHash($model->password);
            // echo "hash:" . $hash;
            $model->password = $hash;                                               
            if ($model->save()) {  
                $auth = \Yii::$app->authManager;
                $authorRole = $auth->getRole('administrador');
                $auth->assign($authorRole, $model->id);
                //echo "<br>Se ha creado el permiso";
            } else {
                die('Error al guardar');
            }

            return $this->redirect(['view', 'id' => $model->id]);
        }

        return $this->render('create', [
                    'model' => $model,
        ]);
    }

Con esta modificación podras vincular el usuario con el Rol de 'administrador' que hemos definido previamente. 

Para comprobar que se ha realizo con éxito puedes, intenta crear un nuevo usuario, al terminar de crearlo confirma entrando al administrador del RBAC en: 

'/web/admin/assignment' 

Donde aparecerá la lista de usuarios de la siguiente manera: 


Y deberás de dar clik en el icono del ojo para ver el detalle como lo muestra la siguiente imagen:





Observar que ya aparece el rol 'administrador'.

Sin embargo aun no podras identificarte, continua con el proceso.

3.7 Modificando el controller de Login

Para que al logearse los redireccione a un controller en especial puede modificar el controller llamado "SiteController.php" de la siguiente manera: 

  
    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ( $model->load(Yii::$app->request->post()) ) {            
            if($model->login()){ // Si se logea con éxito                                 
                return $this->redirect(['/site']);
            }        
            return $this->goBack();
        }

        $model->password = '';
        return $this->render('login', [
            'model' => $model,
        ]);
    }


Finalmente para comprobar con un usuario que si existe, entre a la página de login y escriba el nombre de usuario y contraseña que acaba de crear, si todo esta correcto su pantalla deberá lucir así:


El nombre del usuario en este caso es "x" pero allí debe salir el nombre del usuario que esté logueado. 


4 Administrar permisos de perfil

Hasta este punto ya hemos creado un usuario con un perfil y hecho que un usuario sea capaz de loguearse con dicho perfil, el siguiente paso es aprender a agregar nuevos controladores y hacer grupos de permisos para cada perfil, por lo tanto aqui voy a mostrar como realizar esta operación. 


4.1 Agregar una nueva ruta de controller

Cada controller tiene una dirección ó url especial y el RBAC es como se maneja esto manualmente, el acceso es controlado según el perfil, para configurar esto debe entrar al administrador que normalmente está en la ruta:

web/admin/route

Deberá de ubicar el controller que desea agregar por su nombre de controller, ejemplo:


Se mostrarán todos los controllers que sean semejantes, para agregar todo el grupo del crud podrá agregar por ejemplo:

producto/*

Con esto está indicando que se tendrá acceso a todo el CRUD completo, es decir todos los constrollers incluyen, index, view, create, update, delete.

Deberá de seleccionar el controller deseado y dar clic al botón de color verde, con esto se pasará al lado derecho, lo cual indica que ya agregado la ruta.

Y quedará de esta manera:


4.2 Crear un grupo de permisos y asignar permisos

Para crear un grupo de permisos deberá de entrar a la siguiente url:

web/admin/permission/create

Deberá aparecer una pantalla como esta. 


Deberá de dar clic en el botón de "Create Permission" y aparecerá una pantalla como esta donde en el campo de "name" te recomiendo poner un nombre que describa el grupo de permisos que se desea agregar, ejemplo: "ProductosManager" el nombre puede se cualquiera pero te recomiendo uno que sea fácil de leer.



Al terminar de clic en "Create" con esto se abra creado el grupo de permisos.       



Ahora vamos seleccionar de la parte izquierda el permiso que deseamos agregar y dar permiso en el botón verde para pasarlo a la parte derecha y después dar clic en el botón de "Guardar", con esto quedará dado de alta el permiso a la ruta a este grupo de permisos, yo le recomiendo tener un grupo para cada CRUD.

4.3 Agregar un grupo de permisos a un Rol.

Entre a la sección de roles y seleccione el Rol al cual desea agregar el grupo de permisos en el link: 

web/admin/route

Aparecerá un listado como este.
Seleccione el rol deseado dando clic sobre el icono del ojo para ir al detalle del mismo y seleccione el permiso que desea agregar del listado de la izquierda y oprima el botón verde para agregarlo, para guardar el cambio de clic en el botón de "Update".


Para comprobar que se ha guardado con éxito puede volver a entrar y ver que ya está asignado.

 

5 Comprobar acceso por perfil de Usuario

Para comprobar que en realidad hemos configurado correctamente el perfil de usuario con el controller y con el usuario vamos a tomar como ejemplo un controller, en este caso usaremos el que hemos configurado previamente.

5.1 Verificar acceso público

Deberemos de comprobar que hemos quitado el acceso público en el archivo de configuración, ejemplo en esta lista vamos a comentar la linea que dice:  'producto/*'  con esto pretendemos quitar el acceso público, por lo que si salimos de la sessión y queremos entrar no debemos poder entrar.

  
        'as access' => [
            'class' => 'mdm\admin\components\AccessControl',
            'allowActions' => [
                //'site/*',
                'site/login',
                'site/logout',
                'admin/*',
                'gii/*',
                'usuario/*',
                // 'producto/*'     // <--------------- Comentamos esta linea comprobar acceso         
            ]
        ],


Ahora que hemos comentado esa linea deberás de intentar entrar a ese controller sin sesión y te deberá redirigir al login, por que esa ruta ya no está pública. 

Entonces para comprobar que esta correctamente configurada entra con el usuario que hemos dado de alta he intenta entrar a la misma url de:

/web/producto

Y si tienes acceso, felicidades por que ya hemos terminado. 


Puedes repetir el mismo proceso para futuros controllers y roles.


Referencias:

https://github.com/mdmsoft/yii2-admin
https://github.com/mdmsoft/yii2-admin/blob/master/docs/guide/configuration.md

Identity interface

Actualizado:10-Julio-2020.


Comentarios

  1. Excelente trabajo, me sirvió bastante

    ResponderEliminar
    Respuestas
    1. Gracias. Que bien que te sirvió si encuentras algún error o algún comentario que no está muy claro agradecería tu opinión para mejorarlo.

      Eliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. Disculpa, no hice cambios en la tabla user, quiero usar la misma y funciona hasta cuando trato de asignar un Rol a un usuario (/admin/assignment/assign?id=1). Me sale error: 400 Bad Request
    No se qué pueda ser. Agradezco tu ayuda.

    ResponderEliminar
    Respuestas
    1. Vuelve a revisar que tengas todos los pasos realizados, es muy común que olvidemos algún paso, aun que sinceramente nunca lo he hecho de esa manera como lo hiciste tu. Saludos.

      Eliminar
  4. He implementado varios módulos nuevos, pero no me toma la lista de controladores ni acciones en la lista de rutas. Debo ejecutar una migración o algo ? o debo configurar algo en mis módulos o controladores o en el archivo de configuración ?

    ResponderEliminar
    Respuestas
    1. Ya lo solucioné, el problema es que en el config tenía registrado un módulo que no existía fisicamente en mi proyecto y por lo tanto los demás no los leía.

      Eliminar
    2. A mi me siguen sin aparecer algunos modulos, revise en mi config y no existen otros mas que 'site/login',
      'site/logout',
      'site/*',
      'admin/*',
      'site/error',

      Eliminar

Publicar un comentario

Aprende Yii2


Lo más Visto

Select dependientes en cascada

Tutorial de implementación de calendario de rango de fechas con Karkit en gridView

Cómo enviar correos con Yii2

Creación de PDF con kartik\mpdf\Pdf

hostinger

ventana bienvenida