Laravel 授权策略(Policy)的基本使用

2018-07-03
2分钟阅读时长

Policy(即策略)是在特定模型或者资源中组织授权逻辑的类,用来处理用户授权动作。

比如在博客程序中会有一个 Article 模型,这个模型就会有一个相应的 ArticlePolicy 来对用户的操作进行授权,比如在修改一篇文章时,我们会这样写:

$article = Article::find(1)
// 校验这篇是否属于当前用户
if ($article->user_id == Auth::id()) {
    // 修改文章
}
return ture;

Policy 其实就是将校验的逻辑从控制器转移到相对应的模型策略 (ArticlePolicy) 中。

生成 Policy

使用 php artisan make:policy ArticlePolicy 命令生成 Policy,保存在 app/Policies 目录下。

注册 Policy

然后在 app/Providers/AuthServiceProvider.phppolicies 数组中注册该策略,将 Article 模型与对应的 ArticlePolicy 策略进行绑定。

<?php

namespace App\Providers;

use App\Models\Article;
use App\Policies\ArticlePolicy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * 应用的策略映射。
     *
     * @var array
     */
    protected $policies = [
        Article::class => ArticlePolicy::class,
    ];

    /**
     * 注册任意用户认证、用户授权服务。
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

编写 Policy 校验逻辑

接下来就在 ArticlePolicy 策略中编写校验用户是否拥有修改文章的权限的方法。

<?php

namespace App\Policies;

use App\Models\Article;
use App\User;

class ArticlePolicy
{
    public function update(User $user, Article $article)
    {
        return $user->id == $article->user_id;
    }
}

update 方法中判断文章作者id是否等于当前登录的用户id,返回 true 或 false。true 可以进行修改操作,false 则会抛出没有权限。

使用 Policy

然后就是在控制器中的使用了。

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function edit(Request $request, Article $article)
    {
        // 校验用户是否有操作权限
        $this->authorize('update', $article);
        
        // 更新文章
        $article->fill($request->all());
        $article->save();
    }
}

authorize 的第一个参数表示本次验证使用 ArticlePolicy 里面的 update 方法, $article 实例用来判断使用哪一种策略,当然也可以不用指定具体实例,只需要传递一个类名。

$this->authorize('update', Article::class);
本文作者:她和她的猫
本文地址https://her-cat.com/posts/2018/07/03/basic-usage-of-laravel-authorization-policy/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!