用户授权
简介
除了内置提供的 用户认证 服务外,Laravel 还提供了用户授权和资源访问控制的方案。有很多种方法与辅助函数能帮你处理授权逻辑,在本文档中我们将会涵盖每一种方式。
定义权限
判断一个用户是否允许执行特定行为,最简单的方式就是使用 Illuminate\Auth\Access\Gate
类定义「权限」。
可以在 AuthServiceProvider
文件中定义应用程序的所有权限。举个例子,我们需要定义一个 update-post
的权限,需要判断目前的 User
及 Post
模型 是否有所属关系,也就是「文章」是不是「用户」发的,我们会判断用户的 id
与文章的 user_id
是否一致:
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* 注册应用程序的认证或授权服务。
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->define('update-post', function ($user, $post) {
return $user->id === $post->user_id;
});
}
}
注意,我们并不会检查当指定的 $user
是不是 NULL
。未登录用户或是没有用 forUser
方法指定的用户,Gate
会自动为其 所有权限 返回 false
。
基于类的权限
除了注册 闭包
作为授权的回调,你也可以通过传递包含 类名称
及 方法
的字符串来注册类方法,该类会通过 服务容器 被解析:
$gate->define('update-post', 'Class@method');
拦截授权检查
有时你希望赋予指定用户最高权限,如管理员拥有所有权限,可以使用 before
方法来定义所有授权检查前会被运行的回调:
$gate->before(function ($user, $ability) {
if ($user->isSuperAdmin()) {
return true;
}
});
如果 before
的回调返回一个非 null 的结果,则该结果会被作为检查的结果,并中断后面的其他验证。
你还可以使用 after
方法定义一个当所有授权检查后会被运行的回调。但是,你无法修改 after
回调中授权检查的结果:
$gate->after(function ($user, $ability, $result, $arguments) {
//
});
检查权限
通过 Gate Facade
一旦权限被定义后,我们可以使用不同方式来做「权限检查」。
首先,我们可以使用 Gate
facade 的 check
、allows
或 denies
方法。所有的这些方法会获取权限的名称及参数,并会被传递至权限的回调中。
你 不 需要传递当前登录用户至该方法内,因为 Gate
会自动加载当前登录用户,所以,当通过我们前面定义的 update-post
权限进行检查时,只需传递一个 Post
实例至 denies
方法即可:
<?php
namespace App\Http\Controllers;
use Gate;
use App\User;
use App\Post;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* 更新指定的文章。
*
* @param int $id
* @return Response
*/
public function update($id)
{
$post = Post::findOrFail($id);
if (Gate::denies('update-post', $post)) {
abort(403);
}
// 更新文章...
}
}
allows
方法只是简单的将 denies
方法给颠倒过来,当授权成功时候会返回 true
。check
方法则是 allows
方法的别名。
检查指定用户的权限
如果你想检查