用户授权
简介
除了内置提供的 用户认证 服务外,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 方法的别名。
检查指定用户的权限
如果你想检查