權限管理系統之:表設計及攔截器實現權限攔截

需求說明:

最近要新搞一個平臺,具體不表,後臺這塊需要一個功能可以實現不同人員登錄操作不同的功能,並可以對其他用戶授權。總之,一個簡單的權限系統。

前奏:

起初,這個功能給到一個外包同事去實現,但過了3天還沒有實現完成,經過我瞭解,他用了shiro這個框架,然後又用不好。第一次接觸外包人員,感覺技術體系太亂了,沒人帶,沒人鞭著走是很難有產出的,由於時間又不多,便快刀斬亂麻,棄用shiro,直接使用一個攔截器來實現權限攔截(功能可以簡單實現,時間計劃不可亂)。

表設計:

表結構設計採用了經典的設計 user->role->permission,具體如下:

權限管理系統之:表設計及攔截器實現權限攔截

權限系統表結構設計

表設計說明:

  • user:主鍵uid,name age字段;
  • role:主鍵id,name desc;
  • permission:主鍵id,name:權限名稱,tag:頁面資源(菜單、按鈕)標識,req_url:此權限作用的url;
  • user_role:用戶角色關聯表,多對多,start_time end_time 表示用戶被授予該角色的時間範圍;
  • role_permission:角色權限關聯表,多對多,start_time end_time 表示角色被授權該權限的時間範圍;

攔截器實現權限攔截

最終,配置一個攔截器,攔截所有的頁面請求,並獲取當前登錄的用戶,根據用戶獲取其擁有的所有permission列表,permission的req_url與request.getRequestURI() 直接匹配 來判定是否有權限。攔截器具體實現如下:

  • 檢測RequestMapping方法是否註冊了@NoPermission註解,@NoPermission是一個自定義註解,用來標識該RequestMapping無需權限便可訪問。代碼實現如下:
權限管理系統之:表設計及攔截器實現權限攔截

  • 從accessToken最終獲取到用戶信息UserInfo,具體如下:
權限管理系統之:表設計及攔截器實現權限攔截

  • 判斷該用戶是否為超級管理員,是的話直接跳出攔截器,具體如下:
權限管理系統之:表設計及攔截器實現權限攔截

  • 根據userId最終查詢到該用戶擁有的permission列表,具體實現如下:
權限管理系統之:表設計及攔截器實現權限攔截

  • 獲取到permission列表後與request.getRequestURI()逐一匹配,具體實現如下:
權限管理系統之:表設計及攔截器實現權限攔截

  • 以上條件如果都不成立,則可以認為該用戶無權限訪問該url,可直接返回對於的提示,具體實現代碼如下:

outJson(response, new BaseResp(ErrorCode.PERMISSION_DENIED_ERROR));

總結

綜上,便實現了簡單的一個簡單的基於攔截器的權限攔截功能,實行起來還是非常方便的,畢竟大家都看的懂,不過這其實還有優化空間。

權限攔截功能實現優化

由於數據的設計為 user->role->permission,還有user_role role_permission兩張中間表,因此在實現userService.queryPermissionsByUserId(userId) 這個方法的時候,可想而知對於數據庫的查詢是非常多的,這個非常好辦,我們使用緩存即可,具體實現代碼如下:

權限管理系統之:表設計及攔截器實現權限攔截

最後

至此,一個簡單的權限攔截功能便實現了,花了一天時間,還行看著還順眼。


分享到:


相關文章: