资讯专栏INFORMATION COLUMN

一个简易高效的Laravel的ACL权限系统实现思路

mayaohua / 2177人阅读

摘要:一个简易高效的权限设计系统的实现思路要在上设计一个权限系统,调研了一下等相关权限包,发现效率太低,对于每一次都需要进行连表查询,对于一个控制台菜单来说量居然上了,这是不能忍受的。干脆自己做一套简易的权限结构。

一个简易高效的ACL权限设计系统的实现思路

要在laravel上设计一个acl权限系统,调研了一下Entrust等相关权限包,发现效率太低,对于每一次QueryPrmission、QueryRole都需要进行连表查询,对于一个控制台菜单来说sql量居然上了50+,这是不能忍受的。

干脆自己做一套简易的user-role-permission权限结构。

思路:

缓存用户权限

批量判断权限

实现权限拦截中间件

缓存权限

一般来说,除更改用户权限逻辑代码,其他时候用户的权限是不变的,所以可以缓存用户所有的角色和权限信息。

同时为了提供刷新用户权限的行为,添加了flush permission的功能。

</>复制代码

  1. function cacheUserRolesAndPermissions($user_id , $flash = false){
  2. if ($flash){
  3. Cache::forget("user_r_p_" . $user_id);
  4. return cacheUserRolesAndPermissions($user_id , false);
  5. }else{
  6. return Cache::remember("user_r_p_" . $user_id , 60 ,function() use($user_id){
  7. $res = collect(DB::table("role_user")
  8. ->where("role_user.user_id" , $user_id)
  9. ->join("roles" , "roles.id" , "=" , "role_user.role_id")
  10. ->join("permission_role" , "permission_role.role_id" , "=" ,"role_user.role_id")
  11. ->join("permissions" , "permissions.id" , "=" , "permission_role.permission_id")
  12. ->select(["permissions.name as p_name" , "roles.name as r_name"])
  13. ->get());
  14. $roles = $res->pluck("r_name")->unique();
  15. $pers = $res->pluck("p_name")->unique();
  16. $vals = [
  17. "roles" => $roles->values()->all(),
  18. "pers" => $pers->values()->all()
  19. ];
  20. return $vals;
  21. });
  22. }
  23. }
批量判断权限的思路

对于批量判断权限时候,需要有方法批量返回判断数组。这里借鉴了Entrust的getAbility思路。

</>复制代码

  1. /**
  2. * @param $pers []
  3. * @param $option [] valid_all 是否判断全部权限 return_type boolean/array
  4. */
  5. function hasPermission($pers , $option = []){
  6. $option = array_merge(["valid_all" => false , "return_type" => "boolean"] , $option); //return_type boolean|array|both
  7. if (!is_array($pers)) $pers = [$pers];
  8. $gates = cacheUserRolesAndPermissions(Auth::id());
  9. if ($option["return_type"] == "boolean"){
  10. foreach ($pers as $per){
  11. if (in_array($per , $gates["pers"])){
  12. if (!$option["valid_all"]){
  13. return true;
  14. }
  15. }else{
  16. if ($option["valid_all"]){
  17. return false;
  18. }
  19. }
  20. }
  21. if ($option["valid_all"]) return true;
  22. else return false;
  23. }else if ($option["return_type"] == "array"){
  24. $res = [];
  25. foreach ($pers as $per){
  26. $res[$per] = in_array($per , $gates["pers"]);
  27. }
  28. return $res;
  29. }else{
  30. return null;
  31. }
  32. }
路由拦截中间件

批量判断权限高效实现了页面渲染时候权限判断问题,为了进一步增强系统安全性,需要对路由进行权限匹配拦截。

这里就不贴代码了,主要的意思是对route group内每一次的请求进行权限检查,这里需要注意有些请求含有参数,所以需要路径通配符判断,其次需要对路由方法进行检测。拦截规则类似于:

</>复制代码

  1. $rules = [
  2. "/admin/post/{id}" => ["method" => "DELETE" , "permission" => "post_delete"],
  3. "/admin/post/{id}/edit" => "post_edit", //default any http method
  4. ]

利用这三个思路实现的权限系统简洁、高效,缓存权限之后,基本不会查表即可实现批量权限判断,大大改善了之前权限系统的性能问题。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22394.html

相关文章

  • PHP -Casbin: 支持 ACL、RBAC、ABAC 多种模型 PHP 权限管理框架

    摘要:是一个用语言打造的轻量级开源访问控制框架,目前在开源。采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制基于属性的访问控制等。 showImg(https://segmentfault.com/img/bVbkDJf?w=500&h=220); PHP-Casbin 是一个用 PHP 语言打造的轻量级开源访问控制框架( https://github.com/php...

    rainyang 评论0 收藏0
  • laravel5.1 -- ACL(Access Control List) Policies篇

    摘要:在中,提供了管理授权逻辑以便控制对资源的访问权限。例如,我们可以利用来确定当前的是否有修改一篇文章的权限。 Introduction 在laravel中,Policies提供了管理授权逻辑以便控制对资源的访问权限。例如,我们可以利用poslicies来确定当前的user是否有修改一篇文章的权限。 生成一个PostPolicy $ php artisan make:policy Pos...

    instein 评论0 收藏0
  • Any-基于Laravel5.4新权限管理后台骨架

    摘要:最简化权限管理系统,基于开发。基于开发,唯一优化的是用权限和路由别名绑定,这样代码写好之后就可以直接使用。如果是超级管理员,即使没有这个权限会自动赋予权限给超级管理员角色。默认管理员账号密码。然后正常执行命令其他命令即可。 Any 最简化权限管理系统,基于 Laravel5.4 开发。由于 Laravel5.5 发布推迟,只好先写个 Laravel5.4版本的,后面再升级上去。演示地址...

    Lavender 评论0 收藏0
  • Laravel 工具包推荐--角色/权限管理】

    摘要:在大多数的开发中,角色和权限的管理都是非常重要的一部分。上关于角色和权限管理的包有很多,今天就为大家介绍几个好用的包。缓存在中,为了提高应用的性能,或自动的存储角色和权限数据。 showImg(https://segmentfault.com/img/bVTEb3?w=2200&h=1125); 在大多数的web开发中,角色和权限的管理都是非常重要的一部分。Laravel上关于角色和权...

    xiaoxiaozi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<