directorytree/authorization

原生Laravel授权。

v1.2.0 2024-03-14 19:05 UTC

This package is auto-updated.

Last update: 2024-09-09 17:22:26 UTC


README

一个简单、原生的Laravel角色/权限管理系统。

索引

安装

要开始,请通过Composer包管理器安装Authorization

composer require directorytree/authorization

Authorization服务提供程序将其自己的数据库迁移目录注册到框架中,因此您应在安装包后迁移数据库。Authorization迁移将创建您的应用程序存储角色和权限所需的表

php artisan migrate

现在将DirectoryTree\Authorization\Traits\Authorizable插入到您的App\Models\User模型中

<?php

namespace App\Models;

use DirectoryTree\Authorization\Traits\Authorizable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Authorizable;

    // ...
}

您现在可以执行用户授权。

迁移自定义

如果您不想使用Authorization的默认迁移,您应在您的AppServiceProviderregister方法中调用Authorization::ignoreMigrations方法。您可以使用php artisan vendor:publish --tag=authorization-migrations导出默认迁移。

use DirectoryTree\Authorization\Authorization;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    Authorization::ignoreMigrations();
}

模型自定义

默认情况下,App\Models\User类被注册为可授权用户模型。

您可以自由扩展Authorization内部使用的模型,或创建自己的模型。

通过您的AuthServiceProvider中的Authorization类指示Authorization使用您自己的模型

use DirectoryTree\Authorization\Authorization;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Authorization::useUserModel(\App\Models\User::class);
    Authorization::useRoleModel(\App\Models\Role::class);
    Authorization::usePermissionModel(\App\Models\Permission::class);
}

务必为您的每个自定义模型添加相关的特性

角色模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DirectoryTree\Authorization\Traits\ManagesPermissions;

class Role extends Model
{
    use ManagesPermissions;
}

权限模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DirectoryTree\Authorization\Traits\HasUsers;
use DirectoryTree\Authorization\Traits\HasRoles;
use DirectoryTree\Authorization\Traits\ClearsCachedPermissions;

class Permission extends Model
{
    use HasUsers, HasRoles, ClearsCachedPermissions;
}

使用

Authorization使用原生的Laravel关系,所以如果您不想,您不需要学习新的API。

由于Authorization基于特性的实现,所有Authorization的功能都可以通过您自己的实现进行覆盖或扩展。

管理角色 & 权限

创建权限

use DirectoryTree\Authorization\Permission;

$createUsers = Permission::create([
    'name' => 'users.create',
    'label' => 'Create Users',
]);

创建角色

use DirectoryTree\Authorization\Role;

$admin = Role::create([
    'name' => 'administrator',
    'label' => 'Admin',
]);

将权限授予角色

$admin->permissions()->save($createUsers);

现在将角色分配给用户

$user->roles()->save($admin);

您还可以在Role模型上使用grant()revoke()方法

// Using the permission's name:
$admin->grant('users.create');

// Using a permission model:
$admin->grant($permission);

// Granting multiple permissions:
$admin->grant(['users.create', 'users.edit']);

// Granting a collection of models:
$admin->grant(Permission::all());

// Using a mix of models and permission name:
$admin->grant([$createUsers, 'users.edit']);

您还可以使用grantOnly()方法同步角色的权限

// All permissions will be removed except, except for the given:
$admin->grantOnly('users.create');
// Using the permission's name:
$admin->revoke('users.create');

// Using a permission model:
$admin->revoke($permission);

// Revoking multiple permissions:
$admin->revoke(['users.create', 'users.edit']);

// Revoking a collection of models:
$admin->revoke(Permission::all());

// Using a mix of models and permission name:
$admin->revoke([$createUsers, 'users.edit']);

您还可以使用revokeAll()方法从角色中分离所有权限

$admin->revokeAll();

管理用户 & 权限

您还可以创建特定于用户的权限

$createUsers = Permission::create([
    'name' => 'users.create',
    'label' => 'Create Users',
]);

$user->permissions()->save($createUsers);

与角色一样,您也可以在可授权的User模型上使用grant()revoke()方法

// Using the permission's name:
$user->grant('users.create');

// Using a permission model:
$user->grant($permission);

// Granting multiple permissions:
$user->grant(['users.create', 'users.edit']);

// Granting a collection of models:
$user->grant(Permission::all());

// Using a mix of models and permission name:
$user->grant([$createUsers, 'users.edit']);

您还可以使用grantOnly()方法同步用户的权限

// All permissions will be removed except, except for the given:
$user->grantOnly('users.create');
// Using the permission's name:
$user->revoke('users.create');

// Using a permission model:
$user->revoke($permission);

// Granting multiple permissions:
$user->revoke(['users.create', 'users.edit']);

// Granting a collection of models:
$user->revoke(Permission::all());

// Using a mix of models and permission name:
$user->revoke([$createUsers, 'users.edit']);

检查权限 & 角色

使用Laravel的本地can()方法

if (Auth::user()->can('users.create')) {
    // This user can create other users.
}

在您的控制器中使用Laravel的本地authorize()方法

public function create()
{
    $this->authorize('users.create');

    User::create(['...']);
}

使用Laravel的本地Gate外观

if (Gate::allows('users.create')) {
    //
}

在您的视图中使用Laravel的本地@can指令

@can('users.create')
    <!-- This user can create other users. -->
@endcan

检查权限 & 角色(使用Authorization包方法)

检查权限

// Using the permissions name.
if ($user->hasPermission('users.create')) {
    //
}

// Using the permissions model.
if ($user->hasPermission($createUsers)) {
    //
}

检查多个权限

if ($user->hasPermissions(['users.create', 'users.edit'])) {
    // This user has both creation and edit rights.
} else {
    // The user doesn't have one of the specified permissions.
}

检查用户是否有任何权限

if ($user->hasAnyPermissions(['users.create', 'users.edit', 'users.destroy'])) {
    // This user either has create, edit or destroy permissions.
} else {
    // The user doesn't have any of the specified permissions.
}

检查用户是否有角色

if ($user->hasRole('administrator')) {
    // This user is an administrator.
} else {
    // The user isn't an administrator.
}

检查用户是否有指定的角色

if ($user->hasRoles(['administrator', 'member'])) {
    // This user is an administrator and a member.
} else {
    // The user isn't an administrator or member.
}

检查用户是否有任何指定的角色

if ($user->hasAnyRoles(['administrator', 'member', 'guest'])) {
    // This user is either an administrator, member or guest.
} else {
    // The user doesn't have any of these roles.
}

缓存

默认情况下,所有权限都缓存在一起,以防止在每次请求时检索。

当权限被创建、更新或删除时,此缓存会自动刷新。

如果您想禁用缓存,请调用您的AuthServiceProvider中的Authorization::disablePermissionCache

use DirectoryTree\Authorization\Authorization;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Authorization::disablePermissionCache();
}

缓存键

默认情况下,权限缓存键为 authorization.permissions

要更改缓存键,请在您的 AuthServiceProvider 中调用 Authorization::cacheKey

use DirectoryTree\Authorization\Authorization;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Authorization::cacheKey('my-key');
}

缓存过期

默认情况下,权限缓存每天过期。

要更改此过期日期,请在您的 AuthServiceProvider 中调用 Authorization::cacheExpiresIn

use DirectoryTree\Authorization\Authorization;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Authorization::cacheExpiresIn(now()->addWeek());
}

注册网关

默认情况下,您创建的所有权限都已在 Laravel 的 Gate 中注册。

如果您想禁用此功能,请在您的 AuthServiceProvider 中调用 Authorization::disableGateRegistration

use DirectoryTree\Authorization\Authorization;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Authorization::disableGateRegistration();
}

中间件

Authorization 包含两个您可以用在路由上的实用中间件类。

将它们添加到您的 app/Http/Kernel.php 中。

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

    // The role middleware:
    'role' => \DirectoryTree\Authorization\Middleware\RoleMiddleware::class,

    // The permission middleware:
    'permission' => \DirectoryTree\Authorization\Middleware\PermissionMiddleware::class,
];

添加后,您就可以开始使用了。

注意:当用户使用中间件不满足要求时,会抛出 403 HTTP 异常。

要保护路由,仅允许特定权限访问

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'permission:users.index',
]);

// Multiple permissions:
Route::get('users', [
    'uses' => 'UsersController@index',
    // Users must have index **and** create rights to access this route.
    'middleware' => 'permission:users.index,users.create',
]);

要保护路由,允许特定角色访问

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'role:administrator',
]);

// Multiple roles:
Route::get('users', [
    'uses' => 'UsersController@index',
    // Users must be an administrator **and** a member to access this route.
    'middleware' => 'role:administrator,member',
]);

运行测试

要运行您的应用程序测试,必须在运行测试之前,在 TestCase::setUp() 方法中实例化 PermissionRegistrar,以确保权限正确注册。

use DirectoryTree\Authorization\PermissionRegistrar;
protected function setUp() : void
{
    parent::setUp();

    app(PermissionRegistrar::class)->register();
}