1. 程式人生 > 其它 >Java輕量級許可權認證框架——Sa-token

Java輕量級許可權認證框架——Sa-token

Java輕量級許可權認證框架——Sa-token

技術概述

該技術主要適用於需要完成登入認證、許可權認證、Session會話等功能的場景。在本次的專案中我們需要對管理員的許可權進行管理,除此之外還有對使用者進行登入驗證。因此,學習該技術能夠很好地為我們解決我們專案需要完成的任務內容。

技術詳述

下面通過幾個部分對該技術的實現和使用進行說明

  • 環境的整合

    本次專案我們後端使用的是springboot框架,為了整合satoken,首先,我們需要將Satoken的依賴新增到pom.xml中,然後在application.yml或者application.properties中設定配置,這一個過程還是十分方便簡單的。

    其次,我們需要在專案目錄下建立一個Util類,預設它叫做StpUtil,該類通過呼叫底層封裝的StpLogic實現了許多業務需要用到的方法(都是靜態的)。該類建立完畢後後續的幾個模組可以通過呼叫該類的方法完成。

  • 登入認證

    在完成使用者登入的賬戶驗證後,可以通過呼叫 StpUtil.login(Object id); 對當前會話登入的賬號id進行標記,id的建議引數型別為long | int | String

    我們可以通過呼叫StpUtil.checkLogin() 檢驗當前會話是否已經登入, 如果未登入,則丟擲異常 NotLoginException

    部分程式碼如下:

    	  //errcode為0表示請求成功
            if(errorCode==0){
                //將獲得的openid 作為loginId
                StpUserUtil.setLoginId(code2Session.getString("openid"));
                // 獲取當前會話的token值,將該token值作為skey傳給小程式端作為會話的維護
                String satoken=StpUserUtil.getTokenValue();
                Map map=new HashMap();
                map.put("tokenKey","satoken");
                map.put("tokenValue",satoken);
                return new ResponseDTO(errorCode,"登入成功",map);
            }
            else if(errorCode==-1){
                return new ResponseDTO(errorCode,"系統繁忙,此時請開發者稍候再試",new HashMap<>());
            }
            else if(errorCode==INVALID){
                return new ResponseDTO(errorCode,"code 無效",new HashMap<>());
            }
            else if(errorCode==OFTEN){
                return new ResponseDTO(errorCode,"頻率限制,每個使用者每分鐘100次",new HashMap<>());
            }
            return null;
    
  • 全域性異常攔截

    @ResponseBody
    @ExceptionHandler
    public String handlerException(Exception e, HttpServletRequest request, HttpServletResponse response)
                throws Exception {
            // 不同異常返回不同狀態碼
            String message = "";
            if(e instanceof NotRoleException) {
                // 如果是角色異常
                NotRoleException ee = (NotRoleException) e;
                message="無此角色:" + ee.getRole();
            } else if(e instanceof NotPermissionException) {
                // 如果是許可權異常
                NotPermissionException ee = (NotPermissionException) e;
                message="無此許可權:" + ee.getCode();
            } else if(e instanceof DisableLoginException) {
                // 如果是被封禁異常
                DisableLoginException ee = (DisableLoginException) e;
                message="賬號被封禁:" + ee.getDisableTime() + "秒後解封";
            } else {
                // 普通異常, 輸出:500 + 異常資訊
                throw e;
            }
    
            response.setStatus(403);
            // 返回給前端
            return message;
        }
    
  • 註解鑑權

    • 許可權驗證基於註解,首先Config包下建立攔截器,並註冊
    @Configuration
    public class SaTokenConfigure implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
          
            registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
        }
    }
    
    • 在需要驗證的地方加入註解
        @SaCheckPermission("notice-add")
        @ResponseBody
        @PostMapping("/publish")
        public ResponseDTO publishNotice(@RequestBody @Validated({NoticeDO.Insert.class}) NoticeDO notice){
            noticeService.publishNotice(notice);
            return ResponseUtil.getSuccessResponse("釋出成功",new HashMap<>());
        }
    

    例如公告的釋出,需要有許可權'notice-add',該方法才能生效;否則需要給出許可權不足的提示。

下面給出Satoken的認證流程

使用過程中遇到的問題和解決過程

問題:小程式端使用的介面和後臺管理員使用的介面有重疊,因此比較難以自定義許可權驗證規則,無法配置路由攔截鑑權。

解決方法:通過註解進行鑑權。優點是可以明確地為特定方法加以許可權驗證,缺點是需要對分散在各個角落的程式碼都進行註解新增。

當然還有一種方法,不過由於時間有限來不及修改,就是將小程式端和後臺所需要使用到的介面分包,在不同包下進行管理,這樣就不會出現路由的衝突。

總結

Satoken可以說是目前體驗過最輕量的許可權驗證框架了,它非常方便,上手快速,對新手小白也挺友好,整合的功能也很多,只不過本次實踐中需求沒有那麼多因此使用和體驗到的有限。

Satoken是一款開源的框架,它目前仍然處於頻繁更新進步的時期,時不時就有新的version,之前曾經踩過的坑就是按照開發手冊上面的步驟編寫程式碼,卻發現某個介面始終無法接收引數,一開始以為是引數的格式或內容有問題,檢查了許久,後面查閱它的更新日誌,才發現自己當前的version並還未支援,需要修改pom.xml中的version。

希望將來Satoken能夠越來越強大!

參考文獻

Sa-toekn開發手冊