простое и гибкое управление разрешениями пользователей
Авторизация Laravel и управление разрешениями ролей
простое руководство по гибкой аутентификации и авторизации
Во многих веб-проектах у нас есть разные роли пользователей, взаимодействующих с системой. У каждой роли есть собственное разрешение. Каждая функция системы может быть включена или отключена для этих ролей. Мы можем определить разрешения пользователей в наших кодах и проверить, имеют ли они право выполнять запрошенное действие или нет. Лучшим способом, в основном в более гибких системах, является создание системы управления ролями и авторизацией. Я объясню, как реализовать систему авторизации Laravel и определить права пользователей в зависимости от их ролей.
В этом посте мы сначала управляем пользователями в группах, которые мы назвали ролями. У каждой роли разные разрешения. Чтобы избежать конфликта разрешений, мы предполагаем, что у каждого пользователя есть только одна роль. Во-вторых, авторизация Laravel реализуется промежуточным программным обеспечением. Это промежуточное ПО проверяет разрешение роли пользователя и авторизует запросы пользователей.
Создание роли и разрешений
Чтобы реализовать авторизацию Laravel, мы создадим таблицу ролей и разрешений. Чтобы назначить роли для пользователей, мы создаем таблицу ролей. Миграция для таблицы ролей очень проста:
Schema::create(‘roles’, function (Blueprint $table) {
$table->increments(‘id’);
$table->string(‘name’);
$table->string(‘description’)->nullable();
$table->timestamps();
});
У нас есть идентификатор и имя для ролей. Все пользователи будут управляться в этих ролях. Также есть поле описания, потому что вам может понадобиться небольшая заметка о ролях, чтобы описать каждую роль для себя.
После этого мы добавляем внешний ключ role_id в пользовательскую таблицу. Добавление этого поля в модель пользователя по умолчанию помогает нам в авторизации Laravel.
$table->unsignedInteger(‘role_id’)->index(); $table->foreign(‘role_id’)->references(‘id’)->on(‘roles’);
Теперь поговорим о таблице разрешений. Каждый запрос приводит к методу контроллера. Таким образом, мы сохраняем список всех методов и имя их контроллера в таблице разрешений. Позже мы объясним, как мы собираем этот список и как мы проверяем авторизацию пользователей в Laravel с помощью этой таблицы разрешений.
Schema::create(‘permissions’, function (Blueprint $table) {
$table->increments(‘id’);
$table->string(‘name’)->nullable();
$table->string(‘key’)->nullable();
$table->string(‘controller’);
$table->string(‘method’);
$table->timestamps();
});
Наконец, между ролями и разрешениями создана связь.
Schema::create(‘permission_role’, function (Blueprint $table) {
$table->unsignedInteger(‘permission_id’);
$table->unsignedInteger(‘role_id’);
$table->foreign(‘permission_id’)
->references(‘id’)
->on(‘permissions’)
->onDelete(‘cascade’);
$table->foreign(‘role_id’)
->references(‘id’)
->on(‘roles’)
->onDelete(‘cascade’);
$table->primary([‘permission_id’, ‘role_id’]);
});
Мы создали полную архитектуру пользователей- ›ролей-› разрешений. После этого в этих таблицах будет храниться список доступа. Итак, мы можем легко реализовать авторизацию Laravel, сверяя запросы по этому списку.
Прочтите Документацию по миграции Laravel для получения дополнительной информации о создании таблиц.
Создание списка доступа для разрешений пользователя
Вся цель этого поста - быть динамичным. Особенно в системах с другим типом ролей. Нам нужно создать список разрешений в системе. Также этот список должен обновляться по мере развития системы. Список контроллеров и методов хорошо отображает все разрешения в системе. Каждый маршрут ведет к методу контроллера. Итак, неплохо составить список разрешений, используя список маршрутов.
Для этого я использовал сидер базы данных Laravel. Для начала напишем сеялку ролей. Он создает необходимые нам основные роли и сохраняет их в таблице ролей. Выполнение этой команды artisan создаст для вас RolesSeeder:
php artisan make:seeder RolesTableSeeder
Внутри этого RolesTableSeeder мы создаем наши основные роли:
DB::table(‘roles’)->insert([ [‘name’ => ‘admin’], [‘name’ => ‘operator’], [‘name’ => ‘customer’], ]);
Вы можете добавить столько ролей, сколько вам нужно. Кроме того, вы можете создавать новые роли на своем веб-сайте, когда вам нужна новая.
Второй шаг - создать список авторизации для каждой роли. мы создаем еще один сидер Laravel, в котором заполняем таблицу разрешений:
php artisan make:seeder PermissionTableSeeder
Во-первых, мы получаем список всех маршрутов. Затем мы проверяем базу данных, если разрешение уже сохранено. После этого, если этого разрешения еще нет в таблице, мы вставляем новые разрешения в таблицу разрешений. Ведь мы привязываем все разрешения к роли админа.
$permission_ids = []; // an empty array of stored permission IDs
// iterate though all routes
foreach (Route::getRoutes()->getRoutes() as $key => $route)
{
// get route action
$action = $route->getActionname();
// separating controller and method
$_action = explode(‘@’,$action);
$controller = $_action[0];
$method = end($_action);
// check if this permission is already exists
$permission_check = Permission::where(
[‘controller’=>$controller,’method’=>$method]
)->first();
if(!$permission_check){
$permission = new Permission;
$permission->controller = $controller;
$permission->method = $method;
$permission->save();
// add stored permission id in array
$permission_ids[] = $permission->id;
}
}
// find admin role.
$admin_role = Role::where(‘name’,’admin’)->first();
// atache all permissions to admin role
$admin_role->permissions()->attach($permission_ids);
Авторизация laravel с помощью программного обеспечения
Каждый запрос в Laravel проходит через промежуточное ПО. Зная, что создание промежуточного программного обеспечения RolesAuth выполнит авторизацию Laravel. Вы можете создать промежуточное ПО вручную или с помощью специальной команды:
php artisan make:middleware RolesAuth
Внутри этого промежуточного программного обеспечения мы получаем все разрешения для вошедшего в систему пользователя. Затем мы проверяем, есть ли запрошенное действие в списке разрешений. Если запрошенное действие не может быть найдено в списке разрешений, возвращается ответ с ошибкой 403.
// get user role permissions
$role = Role::findOrFail(auth()->user()->role_id);
$permissions = $role->permissions;
// get requested action
$actionName = class_basename($request->route()->getActionname());
// check if requested action is in permissions list
foreach ($permissions as $permission)
{
$_namespaces_chunks = explode(‘\\’, $permission->controller);
$controller = end($_namespaces_chunks);
if ($actionName == $controller . ‘@’ . $permission->method)
{
// authorized request
return $next($request);
}
}
// none authorized request
return response(‘Unauthorized Action’, 403);
Наконец, вы можете зарегистрировать это промежуточное ПО в Laravel и использовать его в соответствии с вашими требованиями.
Я начал публиковать свой опыт разработки Laravel, здесь вы можете увидеть мой пост о локализации Laravel. Прокомментируйте свои вопросы об этом посте или любые другие вопросы о разработке Laravel в этой области.
Обновление 2020:
Теперь вы можете использовать мою сборку пакета разрешений Laravel на основе этой статьи. Он стал еще лучше, чище и проще для понимания.
https://github.com/amiryousefi/laravel-permission