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能夠越來越強大!