授权(Authorization)
2016-01-18 16:37
239 查看
介绍
除了认证服务,laravel还提供了授权服务,laravel同样提供了一个简单的方式去组织授权的逻辑来控制资源的访问.我们提供了各种各样的方法协助你们组织授权的逻辑,这些都在下面的文档之中。
定义能力
如果用户想要执行某个动作并使用能力,最简单的方式是使用
注意,我们并没用检测$user是否为null,因为如果当前用户没有认证或者指定了特殊的用户不做这个方法的验证,那么gate对象讲自动返回false.
基于类的能力
除了通过注册一个匿名函数,我们也可以注册类的方法,中间通过@符号链接,并且该类需要能够通过service container解析:
拦截授权检测
有的时候你需要对某些特殊的用户忽略所有能力。针对这种情况,可以使用
如果前置方法返回一个不为null的结果,那么这个结果将影响能力的检测.
你也可以定义后置方法,但是后置方法不会影响能力的检测结果:
检测能力
当能力被定义了,我们可以使用多种方式去检测他,首先我们通过
这里也可以使用allows方法,该方法是denies的逆方法,当返回true的时候,则表示已授权.check方法是allows的别名方法。
针对某个特殊的用户授权检测
你可能需要通过Gate facade检测当前认证用户以外的用户,你可以使用forUser方法:
传递多个参数
当然,我们也可以给能力定义多个参数
如果能力定义了多个参数,我们需要以数组的形式将参数传递给
通过User模型检测能力
另外,你也可以同过User模型的实例来检测能力,默认laravel的
当然,can方法只是cannot的逆方法:
在模板中使用
为了方便,laravel提供了一个@can指令去检车当前用户是否用于某个能力的授权,例如:
你也可以结合@can指令使用@else指令:
在表单请求中使用
你也可以选择利用表单请求的
Policies
创建Policies
对于大型的应用,将所有自定义的授权逻辑全部放入
首先让我们生成一个policy来管理我们的post模型,生成一个policy,可以使用
注册Policies
当policy已存在,我们需要使用
编写Policies
当policy已经生成并注册,我们可以为没一个授权的能力添加方法。例如,我们添加一个
你也可以定义更多的方法到里面。例如,你可以需要定义:
注意,所有的policy都可以通过laravel的服务容器解析,这意味着我们可以通过类型提示将policy自动注入.
拦截所有的检测
有的时候,你希望在一个policy中一个特殊的用户忽略所有的ability,针对这种情况,我们可以在policy中定义before方法。这个方法将在这个policy中的所有ability之前执行:
policy方法的调用和基于授权的闭包函数一样。你也可以使用
通过
通过检测他们方法的参数,Gate可以自动确认需要使用哪个policy.比如,我们传递一个Post的实例到
通过User模型
User模型的can和cannot也会自动的利用policy
在模板中使用
通过policy辅助方法
policy方法通过传入的对象的实例来检索需要使用哪个policy.例如,我们传入一个Post的实例到policy中,他将自动返回一个PostPolicy的实例:
控制器授权
默认
如果授权通过,那么这个控制前将继续执行,否则将抛出一个
自动确定policy的方法
通常policy的方法都是符合控制器的方法的。例如:update方法,policy和控制器的方法名都一样。
基于这个结果,laravel允许你简化传递给
除了认证服务,laravel还提供了授权服务,laravel同样提供了一个简单的方式去组织授权的逻辑来控制资源的访问.我们提供了各种各样的方法协助你们组织授权的逻辑,这些都在下面的文档之中。
定义能力
如果用户想要执行某个动作并使用能力,最简单的方式是使用
Illuminate\Auth\Access\Gate类来定义。我们可以在
AuthServiceProvider中定义应用程序中的所有能力。例如我们定义个update-post的能力,他将接受一个当前用户的
Post模型,update-post能力将匹配用户的id和
Post模型的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 { /** * Register any application authentication / authorization services. * * @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,因为如果当前用户没有认证或者指定了特殊的用户不做这个方法的验证,那么gate对象讲自动返回false.
基于类的能力
除了通过注册一个匿名函数,我们也可以注册类的方法,中间通过@符号链接,并且该类需要能够通过service container解析:
$gate->define('update-post', 'Class@method');
拦截授权检测
有的时候你需要对某些特殊的用户忽略所有能力。针对这种情况,可以使用
before方法定义一个闭包,这个方法将在所有能力之前执行。
$gate->before(function ($user, $ability) { if ($user->isSuperAdmin()) { return true; } });
如果前置方法返回一个不为null的结果,那么这个结果将影响能力的检测.
你也可以定义后置方法,但是后置方法不会影响能力的检测结果:
$gate->after(function ($user, $ability, $result, $arguments) { // });
检测能力
当能力被定义了,我们可以使用多种方式去检测他,首先我们通过
Gatefacade的
check,
allows和
denies方法来检测,所有这些方法都需要接受一个能力的名字和一个该能力对应回调函数的参数,你不需要传一个当前的用户到这些方法中,因为Gate会自动将当前认证用户传递到回调中。当然在我们使用的实例传递到update-post能力的时候我们需要提前定义,我只需要将[code]Post
denies方法中。[/code]
<?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller { /** * Update the given post. * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); if (Gate::denies('update-post', $post)) { abort(403); } // Update Post... } }
这里也可以使用allows方法,该方法是denies的逆方法,当返回true的时候,则表示已授权.check方法是allows的别名方法。
针对某个特殊的用户授权检测
你可能需要通过Gate facade检测当前认证用户以外的用户,你可以使用forUser方法:
if (Gate::forUser($user)->allows('update-post', $post)) { // }
传递多个参数
当然,我们也可以给能力定义多个参数
Gate::define('delete-comment', function ($user, $post, $comment) { // });
如果能力定义了多个参数,我们需要以数组的形式将参数传递给
Gate的方法:
if (Gate::allows('delete-comment', [$post, $comment])) { // }
通过User模型检测能力
另外,你也可以同过User模型的实例来检测能力,默认laravel的
App\User模型使用了一个
Authorizabletrait,它将提供两个方法:
can和
cannot。这些方法的使用和
Gatefacade的allows,
denies一样,那么使用之前的例子,我们这个将代码修改为这样:
<?php namespace App\Http\Controllers; use App\Post; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class PostController extends Controller { /** * Update the given post. * * @param \Illuminate\Http\Request $request * @param int $id * @return Response */ public function update(Request $request, $id) { $post = Post::findOrFail($id); if ($request->user()->cannot('update-post', $post)) { abort(403); } // Update Post... } }
当然,can方法只是cannot的逆方法:
if ($request->user()->can('update-post', $post)) { // Update Post... }
在模板中使用
为了方便,laravel提供了一个@can指令去检车当前用户是否用于某个能力的授权,例如:
<a href="/post/{{ $post->id }}">View Post</a> @can('update-post', $post) <a href="/post/{{ $post->id }}/edit">Edit Post</a> @endcan
你也可以结合@can指令使用@else指令:
@can('update-post', $post) <!-- The Current User Can Update The Post --> @else <!-- The Current User Can't Update The Post --> @endcan
在表单请求中使用
你也可以选择利用表单请求的
authorize方法来检测授权:
/** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { $postId = $this->route('post'); return Gate::allows('update', Post::findOrFail($postId)); }
Policies
创建Policies
对于大型的应用,将所有自定义的授权逻辑全部放入
AuthServiceProvider中,将会是一种累赘。laravel允许你讲授权逻辑拆分到多个Policy类中。Policies是一组是基于资源授权的授权逻辑的php类。
首先让我们生成一个policy来管理我们的post模型,生成一个policy,可以使用
make:policy命令,他将生成一个空的
app/Policies文件夹:
php artisan make:policy PostPolicy
注册Policies
当policy已存在,我们需要使用
Gate类来注册他。并且
AuthServiceProvider的类:[/code]policies属性必须包含这些policy类,同时我们也需要指定post模型的policy是[code]PostPolicy
<?php namespace App\Providers; use App\Post; use App\Policies\PostPolicy; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ Post::class => PostPolicy::class, ]; /** * Register any application authentication / authorization services. * * @param \Illuminate\Contracts\Auth\Access\Gate $gate * @return void */ public function boot(GateContract $gate) { $this->registerPolicies($gate); } }
编写Policies
当policy已经生成并注册,我们可以为没一个授权的能力添加方法。例如,我们添加一个
update方法到我们的
PostPolicy类中,它将定义用户时候可以更新post的数据:
?php namespace App\Policies; use App\User; use App\Post; class PostPolicy { /** * Determine if the given post can be updated by the user. * * @param \App\User $user * @param \App\Post $post * @return bool */ public function update(User $user, Post $post) { return $user->id === $post->user_id; } }
你也可以定义更多的方法到里面。例如,你可以需要定义:
show,
destroy,
addComment等方法,去检测Post各个动作的授权。
注意,所有的policy都可以通过laravel的服务容器解析,这意味着我们可以通过类型提示将policy自动注入.
拦截所有的检测
有的时候,你希望在一个policy中一个特殊的用户忽略所有的ability,针对这种情况,我们可以在policy中定义before方法。这个方法将在这个policy中的所有ability之前执行:
public function before($user, $ability) { if ($user->isSuperAdmin()) { return true; } }
检测Policies
policy方法的调用和基于授权的闭包函数一样。你也可以使用
Gatefacade,User模型,在模板中使用@can指令,或则使用policy辅助方法。
通过
Gatefacade
通过检测他们方法的参数,Gate可以自动确认需要使用哪个policy.比如,我们传递一个Post的实例到
denies方法,他将自动使用
PostPolicy类中对应的授权行为:
<?php namespace App\Http\Controllers; use Gate; use App\User; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller { /** * Update the given post. * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); if (Gate::denies('update', $post)) { abort(403); } // Update Post... } }
通过User模型
User模型的can和cannot也会自动的利用policy
if ($user->can('update', $post)) { // } if ($user->cannot('update', $post)) { // }
在模板中使用
@can('update', $post) <!-- The Current User Can Update The Post --> @endcan
通过policy辅助方法
policy方法通过传入的对象的实例来检索需要使用哪个policy.例如,我们传入一个Post的实例到policy中,他将自动返回一个PostPolicy的实例:
if (policy($post)->update($user, $post)) { // }
控制器授权
默认
App\Http\Controllers\Controller基类包含了一个
AuthorizesRequeststrait,这个trait将提供一个
authorize方法,它可以使我们更快捷的对一个行为进行授权,如果没有权限将抛出一个
HttpException的异常。
authorize方法和其他授权方法,如
Gate::allows和$user->can()的参数一样,那么我么就可以这样来快速授权一个更新Post的请求:
<?php namespace App\Http\Controllers; use App\Post; use App\Http\Controllers\Controller; class PostController extends Controller { /** * Update the given post. * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); $this->authorize('update', $post); // Update Post... } }
如果授权通过,那么这个控制前将继续执行,否则将抛出一个
HttpException的异常,这个异常生成一个403的相应返回客户端
AuthorizesRequeststrait也提供一个
authorizeForUser方法,这个方法可以选择特定的用户授权:
$this->authorizeForUser($user, 'update', $post);
自动确定policy的方法
通常policy的方法都是符合控制器的方法的。例如:update方法,policy和控制器的方法名都一样。
基于这个结果,laravel允许你简化传递给
authorize方法的参数,并且ability的授权的方法将自动的确认,这是基于控制器和Policy的方法名相同实现的,例如:这里的
authorize方法在控制器的
update方法中,那么这里将自动的调用
PostPolicy的
update方法:
/** * Update the given post. * * @param int $id * @return Response */ public function update($id) { $post = Post::findOrFail($id); $this->authorize($post); // Update Post... }
相关文章推荐
- CSS3动画基本的转换和过渡
- android.mk 自动寻找cpp文件
- mysql 使用
- sizeof运算符详细总结
- 【转】yum update时候出现Another app is currently holding the yum lock解决方法
- 0R电阻有大用处
- SlidingMenu侧拉菜单
- Debug 模式 和 Release 模式下,一个线程在"编译"上引发的问题
- 解决eclipse中egit中的cannot open git-upload-pack问题
- HIS(医院信息系统HospitalInformationSystem)
- Fold Change和t分布
- 答案是什么
- 关于C++ const 的全面总结
- Scala编程之螺旋
- Log4j.properties配置
- FT系列touch---------suspend和resume的实现
- 逗号表达式
- php中__autoload()方法详解
- IOS开发教程--关于点击IPHONE手机标题栏无法滚动到最顶端问题
- 深入学习jQuery Validate表单验证(二)