摘要:一個簡易高效的權(quán)限設(shè)計系統(tǒng)的實現(xiàn)思路要在上設(shè)計一個權(quán)限系統(tǒng),調(diào)研了一下等相關(guān)權(quán)限包,發(fā)現(xiàn)效率太低,對于每一次都需要進行連表查詢,對于一個控制臺菜單來說量居然上了,這是不能忍受的。干脆自己做一套簡易的權(quán)限結(jié)構(gòu)。
一個簡易高效的ACL權(quán)限設(shè)計系統(tǒng)的實現(xiàn)思路
要在laravel上設(shè)計一個acl權(quán)限系統(tǒng),調(diào)研了一下Entrust等相關(guān)權(quán)限包,發(fā)現(xiàn)效率太低,對于每一次QueryPrmission、QueryRole都需要進行連表查詢,對于一個控制臺菜單來說sql量居然上了50+,這是不能忍受的。
干脆自己做一套簡易的user-role-permission權(quán)限結(jié)構(gòu)。
思路:
緩存用戶權(quán)限
批量判斷權(quán)限
實現(xiàn)權(quán)限攔截中間件
緩存權(quán)限一般來說,除更改用戶權(quán)限邏輯代碼,其他時候用戶的權(quán)限是不變的,所以可以緩存用戶所有的角色和權(quán)限信息。
同時為了提供刷新用戶權(quán)限的行為,添加了flush permission的功能。
function cacheUserRolesAndPermissions($user_id , $flash = false){ if ($flash){ Cache::forget("user_r_p_" . $user_id); return cacheUserRolesAndPermissions($user_id , false); }else{ return Cache::remember("user_r_p_" . $user_id , 60 ,function() use($user_id){ $res = collect(DB::table("role_user") ->where("role_user.user_id" , $user_id) ->join("roles" , "roles.id" , "=" , "role_user.role_id") ->join("permission_role" , "permission_role.role_id" , "=" ,"role_user.role_id") ->join("permissions" , "permissions.id" , "=" , "permission_role.permission_id") ->select(["permissions.name as p_name" , "roles.name as r_name"]) ->get()); $roles = $res->pluck("r_name")->unique(); $pers = $res->pluck("p_name")->unique(); $vals = [ "roles" => $roles->values()->all(), "pers" => $pers->values()->all() ]; return $vals; }); } }批量判斷權(quán)限的思路
對于批量判斷權(quán)限時候,需要有方法批量返回判斷數(shù)組。這里借鑒了Entrust的getAbility思路。
/** * @param $pers [] * @param $option [] valid_all 是否判斷全部權(quán)限 return_type boolean/array */ function hasPermission($pers , $option = []){ $option = array_merge(["valid_all" => false , "return_type" => "boolean"] , $option); //return_type boolean|array|both if (!is_array($pers)) $pers = [$pers]; $gates = cacheUserRolesAndPermissions(Auth::id()); if ($option["return_type"] == "boolean"){ foreach ($pers as $per){ if (in_array($per , $gates["pers"])){ if (!$option["valid_all"]){ return true; } }else{ if ($option["valid_all"]){ return false; } } } if ($option["valid_all"]) return true; else return false; }else if ($option["return_type"] == "array"){ $res = []; foreach ($pers as $per){ $res[$per] = in_array($per , $gates["pers"]); } return $res; }else{ return null; } }路由攔截中間件
批量判斷權(quán)限高效實現(xiàn)了頁面渲染時候權(quán)限判斷問題,為了進一步增強系統(tǒng)安全性,需要對路由進行權(quán)限匹配攔截。
這里就不貼代碼了,主要的意思是對route group內(nèi)每一次的請求進行權(quán)限檢查,這里需要注意有些請求含有參數(shù),所以需要路徑通配符判斷,其次需要對路由方法進行檢測。攔截規(guī)則類似于:
$rules = [ "/admin/post/{id}" => ["method" => "DELETE" , "permission" => "post_delete"], "/admin/post/{id}/edit" => "post_edit", //default any http method ]
利用這三個思路實現(xiàn)的權(quán)限系統(tǒng)簡潔、高效,緩存權(quán)限之后,基本不會查表即可實現(xiàn)批量權(quán)限判斷,大大改善了之前權(quán)限系統(tǒng)的性能問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22394.html
摘要:是一個用語言打造的輕量級開源訪問控制框架,目前在開源。采用了元模型的設(shè)計思想,支持多種經(jīng)典的訪問控制方案,如基于角色的訪問控制基于屬性的訪問控制等。 showImg(https://segmentfault.com/img/bVbkDJf?w=500&h=220); PHP-Casbin 是一個用 PHP 語言打造的輕量級開源訪問控制框架( https://github.com/php...
摘要:在中,提供了管理授權(quán)邏輯以便控制對資源的訪問權(quán)限。例如,我們可以利用來確定當(dāng)前的是否有修改一篇文章的權(quán)限。 Introduction 在laravel中,Policies提供了管理授權(quán)邏輯以便控制對資源的訪問權(quán)限。例如,我們可以利用poslicies來確定當(dāng)前的user是否有修改一篇文章的權(quán)限。 生成一個PostPolicy $ php artisan make:policy Pos...
摘要:最簡化權(quán)限管理系統(tǒng),基于開發(fā)?;陂_發(fā),唯一優(yōu)化的是用權(quán)限和路由別名綁定,這樣代碼寫好之后就可以直接使用。如果是超級管理員,即使沒有這個權(quán)限會自動賦予權(quán)限給超級管理員角色。默認管理員賬號密碼。然后正常執(zhí)行命令其他命令即可。 Any 最簡化權(quán)限管理系統(tǒng),基于 Laravel5.4 開發(fā)。由于 Laravel5.5 發(fā)布推遲,只好先寫個 Laravel5.4版本的,后面再升級上去。演示地址...
摘要:在大多數(shù)的開發(fā)中,角色和權(quán)限的管理都是非常重要的一部分。上關(guān)于角色和權(quán)限管理的包有很多,今天就為大家介紹幾個好用的包。緩存在中,為了提高應(yīng)用的性能,或自動的存儲角色和權(quán)限數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVTEb3?w=2200&h=1125); 在大多數(shù)的web開發(fā)中,角色和權(quán)限的管理都是非常重要的一部分。Laravel上關(guān)于角色和權(quán)...
閱讀 2595·2021-10-25 09:45
閱讀 1254·2021-10-14 09:43
閱讀 2310·2021-09-22 15:23
閱讀 1538·2021-09-22 14:58
閱讀 1944·2019-08-30 15:54
閱讀 3554·2019-08-30 13:00
閱讀 1367·2019-08-29 18:44
閱讀 1580·2019-08-29 16:59