欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel 5.1 中的ACL用户授权及权限检查功能实现教程 有大用

Laravel 5.1 中的ACL用户授权及权限检查功能实现教程

Laravel 5.1 用户授权功能实现

1、引言

Laravel提供的开箱即用的认证功能使得用户注册、登录、退出和密码重置变得便捷和简单。 但是如果你需要控制访问站点特定部分,或者让非管理员打开/关闭特定页面,又或者确保某些用户只能编辑自己发布的东西(如文章),那么 你就需要引入类似BeatSwitch Lock这样的工具或者自己手动编写这样的功能。我们将这样的功能称之为ACL:Access Control Lists(访问控制列表),用于定义用户基于其用户记录属性操作或查看特定事物的权限。 幸运的是,从Laravel 5.1.11开始,Laravel提供了开箱即用的授权功能用于实现上述需求,我们不再需要做任何额外工作,用就是了。
注:在开始本节之前,请参考升级指南将Laravel升级到Laravel 5.1.11,否则不能实现相关功能。

2、能做什么?

Laravel提供的开箱即用的ACL被称作Gate(这并不是一个类似Spark的产品名称,而只是一个类和门面的名称)。 使用Gate类(注入或使用Gate门面)允许我们轻松检查某个用户(当前登录用户或指定用户)是否允许操作特定事物。检查代码如下:
将这段代码放到控制器中,它将会使用定义好的规则update-post来检查当前认证用户是否有权限更新指定文章。 你还可以使用Gate::allows,该方法与denies方法相对,还可以在Blade视图模板中通过@can来使用,还有更多更多,让我们接下来一窥究竟。

3、如果使用?

Laravel ACL建立在“权限”概念之上,权限包括一个键(例如update-post)和一个返回truefalse的闭包(可传入参数)。

3.1 定义权限

让我们在AuthServiceProvider中定义用户更新文章权限update-post如下:
正如你所看到的,定义权限闭包的第一个参数是指定用户,如果当前用户没有通过登录认证,Gate将会自定返回false。 当然,除了闭包之外,还可以通过类方法作为第二个参数来替代闭包,该类会在容器中解析:

3.2 通过Gate门面检查权限

Gate提供如下方法进行权限检查:checkallowsdeniescheckallows功能用法完全一样,而deniesallows功能相反。 如果你使用门面检查权限,则不需要传递用户实例,Gate门面会自动将当前用户传递进来:
如果你在权限中定义了多个参数:
则检查方法如下:
如果你想检查非当前认证用户是否有权限操作,调用方法如下:

3.3 使用Gate注入检查权限

和以往一样,可以注入Gate类而不是使用其门面,注入的类和你在AuthServiceProvider中一样——Illuminate\Contracts\Auth\Access\Gate

3.4 使用User模型检查权限

Laravel的App\User模型现在使用了Authorizabletrait,因此可以使用其提供的cancannot方法,分别对应Gate的allowsdenies方法。 所以我们也可以使用User模型来检查权限:

3.5 在Blade中检查权限

你可以在Blade中使用@can指令来检查权限:
与之相对的是@else指令:

3.6 中止权限检查

如果是管理员或超级用户拥有所有权限怎么做?或者你想要为用户临时切换ACL逻辑又该当如何? Gate提供的before方法允许你在一些特定情况下在执行其他检查前就返回,不再往下检查权限:
或者使用用户自己的时候:

3.7 策略类

随着应用逻辑越来越复杂,要处理的权限越来越多,将所有权限定义在AuthServiceProvider显然不是一个明智的做法,因此Laravel引入了策略类,策略类是一些原生的PHP类,和控制器基于资源对路由进行分组类似,策略类基于资源对权限进行分组管理。 生成策略类 可以使用如下Artisan命令生成PostPolicy策略类:
生成的策略类位于app/Policies目录。 然后我们可以在AuthServiceProviderpolicies属性中注册策略类:
下面我们编辑PostPolicy如下:
注:所有策略类都通过服务容器进行解析,这意味着你可以在策略类的构造函数中类型提示任何依赖,它们将会自动被注入。
检查策略 如果为某个资源类型定义了策略类,Gate将会使用第一个参数来判断检查策略类上的哪个方法。 因此,要检查是否有权限更新某篇文章,只需要传入文章实例和update权限:
当然也可以使用User模型和Blade指令检查权限。 此外,Laravel还提供了一个全局帮助函数policy来检查权限:

3.8 控制器授权

由于大多数授权都会在检查权限失败的情况下退出控制器方法,因此在控制器中检查权限有一条捷径(AuthorizesRequeststrait提供,该trait在基类控制器Controller中被使用):
和我们上面的例子一样,如果授权失败会抛出403错误。 最后,如果你的控制器方法名和策略类中的方法名相同,例如都是update,则可以省略authorize的第一个参数:
此外,AuthorizesRequests也提供了对非当前认证用户权限检查的支持:
声明:本文参考Matt Stauffer的这篇文章:ACL (Access Control List) Authorization in Laravel 5.1

上一篇: Laravel 5.1用户认证(三) —— 使用Socialite实现GitHub登录认证

下一篇: Laravel 5.1 中创建自定义 Artisan 控制台命令实例教程





来自  https://xueyuanjun.com/post/1337

普通分类: