定义授权
Laravel 在 app/Providers/AuthServiceProvider.php
的 boot
方法里定义授权,有两种形式。
形式一
1 | Gate::define('update articles', function ($user, $article) { |
形式二
1 | Gate::define('update articles', 'ArticlePolicy@update'); |
手动创建 ArticlePolicy
类
1 |
|
这两种形式的区别在于,授权逻辑是写在闭包里,还是 PHP 类方法里。闭包或方法最终都返回一个布尔值,true 表示有权限,false 表示没权限。
使用授权
有五种使用授权的方式:
- Gate 门面:
1 | Gate::allows('update articles', $article); |
和1
Gate::denies('update articles', $article);
Controller:
1
$this->authorize('update articles', $article);
Blade 模板:
1
2
3@can('update articles', $article)
<!--如果定义时候没有第二个参数-->
@can('system')
和1
@cannot('update articles', $article)
和1
2
3
4
5@can('update', $post)
<!-- 当前用户可以更新博客 -->
@elsecan('create', $post)
<!-- 当前用户可以新建博客 -->
@endcan
指令。
- User Model 实例:
1
$user->can('update articles', $article);
和1
$user->cannot('update articles', $article);
- 路由
1
2
3
4<!--定义时候没有第二个参数-->
Route::group(['middleware' => 'can:system'], function(){
});
两种定义授权对比
有些时候,直接用基于闭包的形式定义授权很不方便,特别是对某个资源(比如文章)基本的增、删、改、查操作。
1 | Gate::define('view articles', function ($user, $article) { |
如果再有一个视频资源的话,又得定义这四个方法了,这些方法堆在一起,很长。那么如果改成基于 PHP 类方法的形式,就好看一些了。
1 | Gate::define('view articles', 'ArticlePolicy@view'); |
1 |
|
因为分类写了,所以定义授权的地方,看起来就比较清爽了。
更简洁的定义授权形式
为了能更加清爽地定义和使用授权,Laravel 引入了 Policy。在 AuthServiceProvider
的 policies
数组属性里添加授权映射关系即可!
1 | /** |
所有与 Article Model 有关的授权逻辑都写在 ArticlePolicy
里,你可以用 make:policy
Artisan 命令生成他。Policy 只是在普通 PHP 类基础上添加了一个 HandlesAuthorization
trait。
创建策略类
1 | php artisan make:policy ArticlePolicy |
定义策略类
1 |
|
而且使用起来也非常方便。
1 | $user->can('view', $article); |
$article
是 Article Model 实例对象, Laravel 发现是对 Article Model 资源做授权判断,根据在 $policies
中定义的授权映射关系,自动找到 ArticlePolicy
下的 view
、create
、update
和 delete
方法。
当然,授权方法可自定义。比如我在 ArticlePolicy
下自定义了一个方法 xxx
,那么就可以直接用了。
1 | $user->can('xxx', $article); |
但有一个方法是特殊的 ——before
,在 Policy 中会在所有方法执行前调用,经常用到的地方就是处理管理员授权逻辑。
1 | public function before($user, $ability) |