Laravel--介绍 Laravel 授权方式 Gate 和 Policy

两种形式

Laravel 在 AuthServiceProvider 的 boot 方法里定义授权,有两种形式。

Gate::define('update articles', function ($user, $article) {
    return $user->id == $article->user_id;
});

Gate::define('update articles', 'ArticlePolicy@update');
<?php

namespace App\Policies;

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

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

这两种形式的区别在于,授权逻辑是写在闭包里,还是 PHP 类方法里。闭包或方法最终都返回一个布尔值,true 表示有权限,false 表示没权限。

使用授权

有四种使用授权的方式:

  1. Gate 门面:Gate::allows('update articles', $article) 和 Gate::denies('update articles', $article)
  2. Controller:$this->authorize('update articles', $article)
  3. Blade 模板:@can('update articles', $article) 和 @cannot('update articles', $article) 指令。
  4. User Model 实例:$user->can('update articles', $article) 和 $user->cannot('update articles', $article)

Policy

有些时候,直接用基于闭包的形式定义授权很不方便,特别是对某个资源(比如文章)基本的增、删、改、查操作。

Gate::define('view articles', function ($user, $article) {
    return true;
});

Gate::define('create articles', function ($user) {
    return true;
});

Gate::define('delete articles', function ($user, $article) {
    return $user->id == $article->user_id;
});

Gate::define('update articles', function ($user, $article) {
    return $user->id == $article->user_id;
});

如果再有一个视频资源的话,又得定义这四个方法了,这些方法堆在一起,很长。那么如果改成基于 PHP 类方法的形式,就好看一些了。

Gate::define('view articles',  'ArticlePolicy@view');
Gate::define('create articles', 'ArticlePolicy@create');
Gate::define('delete articles', 'ArticlePolicy@delete');
Gate::define('update articles', 'ArticlePolicy@update');
<?php

namespace App\Policies;

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

class ArticlePolicy
{
    public function view(User $user, Article $article)
    {
        return true;
    }

    public function create(User $user)
    {
        return true;
    }

    public function delete(User $user, Article $article)
    {
        return $user->id == $article->author_id;
    }

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

因为分类写了,所以定义授权的地方,看起来就比较清爽了。

为了能更加清爽地定义和使用授权,Laravel 引入了 Policy。在 AuthServiceProvider 的 policies 数组属性里添加授权映射关系即可!

/**
 * The policy mappings for the application.
 *
 * @var array
 */
protected $policies = [
    Article::class => ArticlePolicy::class,
];

所有与 Article Model 有关的授权逻辑都写在 ArticlePolicy 里,你可以用 make:policy Artisan 命令生成他。Policy 只是在普通 PHP 类基础上添加了一个 HandlesAuthorization trait。

<?php

namespace App\Policies;

use App\User;
use App\Models\Article;
use Illuminate\Auth\Access\HandlesAuthorization;

class ArticlePolicy
{
    use HandlesAuthorization;

    public function view(User $user, Article $article)
    {
        return true;
    }

    public function create(User $user)
    {
        return true;
    }

    public function delete(User $user, Article $article)
    {
        return $user->id == $article->author_id;
    }

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

而且使用起来也非常方便。

$user->can('view', $article);
$user->can('create', Article::class);
$user->can('update', $article);
$user->can('delete', $article);

$article 是 Article Model 实例对象, Laravel 发现是对 Article Model 资源做授权判断,根据在 $policies 中定义的授权映射关系,自动找到 ArticlePolicy 下的 viewcreateupdate 和 delete 方法。

当然,授权方法可自定义。比如我在 ArticlePolicy 下自定义了一个方法 xxx,那么就可以直接用了。

$user->can('xxx', $article);

但有一个方法是特殊的 ——before,在 Policy 中会在所有方法执行前调用,经常用到的地方就是处理管理员授权逻辑。

public function before($user, $ability)
{
    if ($user->isSuperAdmin()) {
        return true;
    }
}

转自:https://learnku.com/articles/5479/introduce-laravel-authorization-mode-gate-and-policy

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值