使用 authorizeResource 简化你的 Resource Controller 用户授权
用户授权
众所周知,Laravel 在5.1版本的时候引入了用户授权系统。使用用户授权系统有两种方式,gates 和策略。他们具体的区别 文档里说的很详细了,这里不再阐述。一般我们都会使用策略来验证 Resource Controller
,类似如下的代码:
/**
* 新建博客
*
* @param Request $request
* @return Response
*/
public function create(Request $request)
{
$this->authorize('create', Post::class);
// 当前用户可以新建博客...
}
或者直接使用$this->authorize(Post::class)
不指明验证的权限,Laravel 会直接根据函数名来判断使用何种权限。虽然已经很方便了,但是发现了没有我们还是需要在每一个控制器里面都写一次$this->authorize(Post::class)
来进行权限判断。有没有觉得很繁琐?其实我们有更好的解决办法!
authorizeResource
解决办法就是我们只需要在控制器的construct
函数里面加一句:
/**
* PostController constructor.
*/
public function __construct()
{
$this->authorizeResource(Post::class);
}
Done,每一个控制器方法的逻辑在运行前都会自动进行权限判断,不通过就会自动返回403错误。What?很神奇有没有,是不是感觉和 Laravel 这个框架一样,像一个魔术。其实authorizeResource
这个函数内部使用了中间件验证这一特性来完成自动鉴权。通过读取resourceAbilityMap
返回的权限映射数组为每一个控制器方法添加相应的权限验证中间件。具体的源码我们在此不做分析,有兴趣的同学可以自行研究。不过使用这个特性我们还需要注意几个地方。
提示
第一个就是resourceAbilityMap
函数。我们前面提过,Laravel 会通过读取这个函数返回的权限映射数组,来找到每个控制器方法相应的权限验证函数。默认的resourceAbilityMap
函数长这样:
/**
* Get the map of resource methods to ability names.
*
* @return array
*/
protected function resourceAbilityMap()
{
return [
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
];
}
可以看到每一个 Resouce Controller
方法都对应着相应的权限验证函数名。如果你的控制器里有默认资源控制器不存在的方法,你就需要在控制器里面 override 这个函数。如:
protected function resourceAbilityMap()
{
return [
'index' => 'list',
'datatables' => 'list', // Here, a new resource method.
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
];
}
第二个需要注意的地方是 v5.4.20 版本之前,使用resourceAbilityMap
添加的自定义验证函数是必须指定模型实例的,很显然这是不合理的。所以 v5.4.20 之后你可以在控制器里定义methodsWithoutModels
函数来返回不需要指定模型实例的方法。如:
protected function resourceMethodsWithoutModels()
{
// This new resource method doesn't need any parameter, so you can add it here.
return ['index', 'datatables', 'create', 'store'];
}
新版本的改进是不是让你觉得这个方法使你的用户授权更加如鱼得水?其实不光是资源控制器,一般的控制器也能使用这个办法来进行用户授权,来使你的代码更简洁,美观。
推荐
最后,如果有同学对用户授权这一方面还是弄得不是很清楚的,推荐可以读一读 Laravel Main Contributor-Joseph Silber 的这篇关于用户授权的文章。还有他的bouncer,真心是 Laravel 上用过最舒服也最强大的权限控制系统扩展包。
写在最后
其实 Laravel 有好多东西是文档里没有提到的,很多 Laravel 用户也会在 twitter 上分享一些很巧妙的小技巧。以后我会发一些能让你醍醐灌顶的小技巧在专栏里,希望你能喜欢 :tada:
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: