Laravel 权限策略

310 阅读1分钟

Laravel 默认支持Gate和Policy权限,若使用了Sanctum扩展也可以使用token alility策略

Gate

Illuminate\Auth\Access\Gate实例类,define定义规则,allowscheck等检查是否符合规则

Policy

  • 支持根据模型自动检测关联策略类,规则为Model关联ModelPolicy,可用Gate::guessPolicyNamesUsing自定义检测规则
  • 控制器继承Illuminate\Foundation\Auth\Access\AuthorizesRequests类使用authorizeauthorizeResource等方法检查是否有权限,或直接使用$request->user()->cannot('create', Model::class);

FlightController

// 资源方式绑定各操作权限
public function __construct()
{
    $this->authorizeResource(Flight::class, 'flight');
}

// 单独操作权限验证
public function create(Request $request)
{
    $this->authorize('create', Flight::class);
    // $request->user()->cannot('create', Flight::class); // 另外一种检查方式
}
  • 路由中间件方式检查权限
Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post'); // post直接对应Post模型

Route::post('/post', function () {
    // The current user may create posts...
})->middleware('can:create,App\Models\Post');
  • blade模板支持@cannot

Illuminate\Foundation\Support\Providers\AuthServiceProvider

// 注册策略,模型绑定策略
protected $policies = [
    // Flight::class => FlightPolicy::class // 支持自动识别,可不配置
];

Illuminate\Auth\Access\Gate

// 实例化策略类
protected function resolveAuthCallback($user, $ability, array $arguments)
{
    // 使用policy策略
    if (isset($arguments[0]) &&
        ! is_null($policy = $this->getPolicyFor($arguments[0])) &&
        $callback = $this->resolvePolicyCallback($user, $ability, $arguments, $policy)) {
        return $callback;
    }

    // 使用Gate
    if (isset($this->stringCallbacks[$ability])) {
        [$class, $method] = Str::parseCallback($this->stringCallbacks[$ability]);

        if ($this->canBeCalledWithUser($user, $class, $method ?: '__invoke')) {
            return $this->abilities[$ability];
        }
    }

    if (isset($this->abilities[$ability]) &&
        $this->canBeCalledWithUser($user, $this->abilities[$ability])) {
        return $this->abilities[$ability];
    }

    return function () {
        //
    };
}

Sanctum Ablility

App\Http\Kernel

protected $routeMiddleware = [
    ...
    
    'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
    'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
];

增加权限规则

Route::delete('flight/{flight}', [\App\Http\Controllers\FlightController::class, 'destroy'])
    ->middleware(['auth:sanctum', 'ability:destroy']);

token增加行为权限

$user->createToken('token-name', ['server:update'])->plainTextToken;