Laravel 授權系統 - 自定義引數

licxisky發表於2018-06-24

本文基於 laravel 5.5
在閱讀本文前,請先瀏覽一下 laravel 5.5 使用者授權

php artisan make:policy PostPolicy --model=Post

我們用上面的命令生成的策略檔案會含有四個方法(已去除所有註釋):

<?php
namespace App\Policies;
use App\User;
use App\Models\Project;
use Illuminate\Auth\Access\HandlesAuthorization;

class ProjectPolicy
{
    public function view(User $user, Project $project)
    {
        //
    }

    public function create(User $user)
    {
        //
    }

    public function update(User $user, Project $project)
    {
        //
    }

    public function delete(User $user, Project $project)
    {
        //
    }
}

這四個方法對應的是 資源控制器的 CRUD 方案,也就是增、刪、查、改。
我們一般會在控制器中使用:

public function update(ProjectRequest $projectRequest, Project $project)
{
    $this->authorize('update', $project);
    ...
}

當然,在策略方法名和控制器方法名一致時,有更加優美的寫法(請參照 laravel 5.2 使用者授權 - 自動判斷授權策略方法 ):

public function update(ProjectRequest $projectRequest, Project $project)
{
    $this->authorize($project);
    ...
}

注:策略中的 view 對應的是 show 方法

很多時候,我們還得自己定義策略方法,一般情況與自動生成的方法無異,比如:

...
// Project move
public function move(User $user, Project $project)
{
    //
}
...

但,如果方法的引數與策略對應的 Model 不一致,按照原有的方法使用會一直授權失敗,403
例:
一個部門(Department)有很多成員(User),專案(Project)屬於部門,只有部門的成員可以建立專案
我們重寫一下 create 方法,兩個引數, User - 當前使用者,Department - 專案屬於的部門

...
public function create(User $user, Department $department)
{
    //判斷使用者是否屬於該部門
    return $department->users()->whereId($user->id)->exists();
}
...

我們要按照一下使用方法才能成功呼叫策略:

public function create(Department $department)
{
     $this->authorize('create', [Project::class, $department]);
     // $this->authorize([Project::class, $department]);
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章