среда, 28 сентября 2016 г.

Подключение yii2-user и yii2-admin для управления пользователями и правами доступа

Как настроить управление пользователями и правами доступа в Yii2 с нуля.

Будем использовать приложение Yii2 Advanced, подключим модули "yii2-user" и "yii2-admin".

Если у вас уже есть готовое приложение, шаги с 1 по 5 можно пропустить.

1. Создаём проект по шаблону Advanced.

Здесь предполагается, что вы уже настроили Composer. Если нет, см. документацию к шаблону.

composer create-project --prefer-dist yiisoft/yii2-app-advanced yii2-user-combo.local

cd yii2-user-combo.local
init 
0
yes

2. Удаляем миграцию стандартных юзеров, она нам не нужна: "console/migrations/m130524_201442_init.php".

3. Добавляем файлы ".htaccess" в папки "/frontend/web", "/backend/web", а также в корень проекта.

В моём примере, фронтенд будет доступен по адресу "http://yii2-user-combo.local".

Бэкенд по адресу "http://yii2-user-combo.local/admin".

/.htaccess

Options -Indexes
Options FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^(.*)$ http://%1/$1 [L,R=301]

RewriteCond %{REQUEST_URI} ^/admin/$
RewriteRule ^(admin)/$ /$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^admin(/.+)?$ /backend/web/$1 [L,PT]

RewriteCond %{REQUEST_URI} ^.*$
RewriteRule ^(.*)$ /frontend/web/$1

/backend/web/.htaccess

# use mode rewrite for pretty URL support
RewriteEngine on
# if a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward the request to index.php
RewriteRule . index.php

/frontend/web/.htaccess

<IfModule mod_rewrite.c>
        Options +FollowSymlinks

        # Включаем mod_rewrite и перенаправляем со слэша
        RewriteEngine On
        RewriteBase /
        RewriteCond %{HTTP_HOST} (.*)
        RewriteCond %{REQUEST_URI} /$ [NC]
        RewriteRule ^(.*)(/)$ $1 [L,R=301]

        # Если это папка или файл, открываем ее/его
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        # В противном случае перенаправляем на index.php
        RewriteRule . index.php
</IfModule>


4. Создаём БД, указываем её в конфиге "common/config/main-local.php".

5. Настраиваем конфиги.

backend/config/main.php
    'components' => [
        'request' => [
            ...
            'baseUrl'=>'/admin',
        ],

common/config/main.php
    'language' => 'ru-RU',
    ...
    'components' => [
        ...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
        ],

frontend/config/main.php
    'components' => [
        'request' => [
            // Избавляемся от /frontend/web
            'baseUrl' => '',
            ...
        ],

6. Ставим "yii2-user".

composer require dektrium/yii2-user

7. Убираем из конфига компонент "user", вместо него подключаем дектриумовский модуль.

Настройку модуля пользователей сделаем только для бэкенда. Для фронтенда настройки будут аналогичные.

backend/config/main.php
        'modules' => [
// ID модуля должен обязательно быть "user", иначе модуль не загрузится.
            'user' => [
                'class' => 'dektrium\user\Module',
'admins' => ['MegaAdmin'], // Хардкод для админского пользователя. После настройки прав доступа, нужно удалить эту строку.
            ],
        ],        

8. Подключаем консольные команды.

console/config/main.php
'modules' => [
            'user' => [
                'class' => 'dektrium\user\Module',
            ],
        ],

9. Создаём таблицы для пользователей.

yii migrate --migrationPath=@vendor/dektrium/yii2-user/migrations

10. Убираем неиспользуемые действия из контроллеров.

backend/controllers/SiteController.php

Приводим "behaviors" к такому виду.

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['error'],
                    'allow' => true,
                ],
                [
                    'actions' => ['index'],
                    'allow' => true,
                    'roles' => ['@'],
                ],
            ],
        ],
    ];
}


Убираем лишние действия.
public function actionLogin()
public function actionLogout()

11. Удаляем файл представления
/backend/views/site/login.php

12. Меняем в файле
/backend/views/layouts/main.php

/site/login на /user/security/login

/site/logout на /user/security/logout

13. Ставим расширение "yii2-admin".

composer require mdmsoft/yii2-admin

14. Настраиваем конфиги.

backend/config/main.php
    'bootstrap' => [
        ...
        'users-admin',
    ],
...
    'modules' => [
...
// ID модуля может быть любой.
        'users-admin' => [
            'class' => 'mdm\admin\Module',
            // Отключаем шаблон модуля,
            // используем шаблон нашей админки.
            'layout' => null,
        ]
    ],        
...
    'as access' => [
        'class' => 'mdm\admin\classes\AccessControl',
        // Маршруты, открытые по умолчанию всегда.
        // Открываем только для начальной разработки.
        // Как только основные данные о ролях заполнены,
        // убираем отсюда всё лишнее.
        'allowActions' => [
            // Маршруты модуля пользователей.
            // Логин и так разрешён, но разлогиниться 
            // без этой настройки и без настроенных ролей не получится.
            'user/*',
            'site/*',
            'users-admin/*',
            'debug/*',
        ]
    ],

common/config/main.php
    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
        ],

15. Добавляем ассет для корректного отображения админки в нашем шаблоне.

backend\assets\AppAsset.php
    public $depends = [
        ...
        'dee\adminlte\AdminlteAsset',
    ];

16. Применяем миграции для использования RBAC.

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

17. Применяем миграции для редактирования меню.

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

18. Всё готово.

Управление правами доступа:
http://yii2-user-combo.local/admin/users-admin/

Управление пользователями:
http://yii2-user-combo.local/admin/user/admin

Настройки профиля:
http://yii2-user-combo.local/admin/user/settings/profile

Полный список маршрутов модуля пользователей: https://github.com/dektrium/yii2-user/blob/master/docs/available-actions.md



P.S. Можно подключать расширение "dektrium/yii2-rbac" для управления правами доступа.

Но расширение "mdmsoft/yii2-admin" удобнее.

Оба расширения позволяют полноценно настраивать права доступа.

Преимущества "yii2-admin":

1. Более удобное редактирование прав доступа.

2. Помощник для вывода меню с учётом прав доступа.

3. Редактор меню.

Преимущества "yii2-rbac":

1. Удобно создавать консольные миграции прав доступа.

2. Есть интеграция с yii2-user в виде общей админки.

17 комментариев:

  1. а как быть с модулями которые подключены в common (то есть доступны для пользовательской и административной части), к примеру нужно что бы было из frontend было доступно только действие index, а из бекэнд было лишь доступно действие edit и create ?

    Настроил, что бы действие edit и create было доступно лишь главным админам, и не доступно менеджерам которые имеют доступ к админке(backend), а во frontend эти действия edit и create без каких либо ограничений)


    ОтветитьУдалить
    Ответы
    1. Сделайте проверку на авторизованного пользователя. Неавторизованному пользователю (гостю) разрешаете только просмотр без редактирования.

      Ну а для авторизованных вы уже настроили права доступа.

      Для того, чтобы во фронтенде проверялись права доступа, пропишите в конфиге настройки, аналогичные бэкенду.

      Удалить
  2. 7. Убираем из конфига компонент "user", вместо него подключаем дектриумовский модуль.
    Думаю, что следует более точно описать из какого файла и какого раздела все удалять

    ОтветитьУдалить
  3. 15. Добавляем ассет для корректного отображения админки в нашем шаблоне.

    backend\assets\AppAsset.php
    public $depends = [
    ...
    'dee\adminlte\AdminlteAsset',
    ];

    Перед этим надо установить тему отсюда: https://github.com/deesoft/yii2-adminlte

    ОтветитьУдалить
  4. 'as access' => [
    'class' => 'mdm\admin\classes\AccessControl',
    // Маршруты, открытые по умолчанию всегда.
    // Открываем только для начальной разработки.
    // Как только основные данные о ролях заполнены,
    // убираем отсюда всё лишнее.
    'allowActions' => [
    // Маршруты модуля пользователей.
    // Логин и так разрешён, но разлогиниться
    // без этой настройки и без настроенных ролей не получится.
    'user/*',
    'site/*',
    'users-admin/*',
    'debug/*',
    ]
    ],

    'mdm\admin\classes\AccessControl' - ошибка.
    'mdm\admin\components\AccessControl' - правильно

    ОтветитьУдалить
  5. Спасибо за статью. Пока устанавливается yii2-admin..
    А у меня вопрос по более ранним шагам.
    Уже много раз пытался сделать админку без поддомена, но пока, получилось, только, при помощи создания символьной ссылки на бекенд...
    У Вас описан способ с htaccess-ами, но при переходе на ../admin по прежнему 404.
    Может быть я что-то упускаю?
    rewrite включен, установка точно по гитхабовской инструкции для apache2

    ОтветитьУдалить
    Ответы
    1. Где-то напутали значит. Смотрите в отладочной панели, что за ошибка.

      Удалить
    2. Этот комментарий был удален автором.

      Удалить
    3. yii\base\InvalidRouteException: Unable to resolve the request "admin". in /home/a35b62/sites/advanced/html/vendor/yiisoft/yii2/base/Module.php:532

      Удалить
  6. Композер что-то проверял часов 5 после чего сожрал всю оперативу и намертво повесил систему.
    Ну его нафиг такие расширения

    ОтветитьУдалить
    Ответы
    1. Это скорее ваш композер или "asset-plugin" устарели, а не расширение тупит. Обновляйтесь.

      Удалить
  7. Нужно было версию допиать mdmsoft/yii2-admin "~2.0" - у Вас в статье без версии

    ОтветитьУдалить
  8. Этот комментарий был удален автором.

    ОтветитьУдалить
  9. теперь все самые интересные страницы админки ругаются на права доступа - 403
    как теперь себя админом назначить?

    ОтветитьУдалить
    Ответы
    1. Разобрался... MegaAdmin..
      А с админкой, видимо, нужно apache2 настроить на один адрес без поддомена или вообще для бекенда апачу не указывать параметров.
      Спасибо за статью.
      Теперь буду курить как с этим всем управляться (:

      Удалить
    2. На здоровье. Рад, что у вас получилось разобраться.

      Для апача, в настройках хоста вебрут указывает на корневую папку приложения. В этой папке лежит общий htaccess, который перенаправляет либо в backend либо в frontend. В них уже лежат свои файлы htaccess. То есть всего их три. Все приведены в статье.

      Ну и параметры в конфигах, тоже нужно сверить со статьёй. Все приведённые парамтеры важны для правильной работы маршрутизатора.

      Удалить