微服務網關SpringCloudGateway+SaToken鑒權

目錄

概念

前置知識回顧

拿到UserInfo 用于自定義權限和角色的獲取邏輯

最后進行要進行 satoken 過濾器全局配置


概念

做權限認證的時候 我們首先要明確兩點

我們需要的角色有幾種 我們需要的權限有幾種

角色 分兩種

ADMIN 管理員 :可管理商品

CUSTIOMER 普通用戶 :

權限 分四種

BASIC 基本權限 :可瀏覽商品

AUTU 已實名認證權限 :可下單支付

FROZEN 被凍結用戶權限

NONE 沒有任何權限

前置知識回顧

在閱讀完 sa-token 的文檔后

我發現原來權限驗證如此簡單

我們只需要 使用StpUtil即可

這個在開發博客的時候寫過相關的

// 用戶已存在,直接登錄
StpUtil.login(userInfo.getUserId(), new SaLoginModel().setIsLastingCookie(loginParam.getRememberMe()).setTimeout(DEFAULT_LOGIN_SESSION_TIMEOUT));
// 將用戶信息存入會話
StpUtil.getSession().set(userInfo.getUserId().toString(), userInfo);
// 創建登錄結果對象
LoginVO loginVO = new LoginVO(userInfo);
// 返回登錄成功響應
return Result.success(loginVO);

拿到UserInfo 用于自定義權限和角色的獲取邏輯

我們在用 StpUtil 去拿這個登錄信息

進行校驗

很容易理解 我們在登錄模塊 放入了一個 UserInfo 對象進去

包含了用戶了信息

package cn.hollis.nft.turbo.api.user.response.data;import cn.hollis.nft.turbo.api.user.constant.UserRole;
import cn.hollis.nft.turbo.api.user.constant.UserStateEnum;
import com.github.houbb.sensitive.annotation.strategy.SensitiveStrategyPhone;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;import java.util.Date;/*** @author Hollis*/
@Getter
@Setter
@NoArgsConstructor
public class UserInfo extends BasicUserInfo {private static final long serialVersionUID = 1L;/*** 手機號*/@SensitiveStrategyPhoneprivate String telephone;/*** 狀態** @see UserStateEnum*/private String state;/*** 區塊鏈地址*/private String blockChainUrl;/*** 區塊鏈平臺*/private String blockChainPlatform;/*** 實名認證*/private Boolean certification;/*** 用戶角色*/private UserRole userRole;/*** 邀請碼*/private String inviteCode;/*** 注冊時間*/private Date createTime;public boolean userCanBuy() {if (this.getUserRole() != null && !this.getUserRole().equals(UserRole.CUSTOMER)) {return false;}// 判斷買家狀態if (this.getState() != null && !this.getState().equals(UserStateEnum.ACTIVE.name())) {return false;}// 判斷買家狀態if (this.getState() != null && !this.getCertification()) {return false;}return true;}
}

我們sa-token 提供的接口中重寫權限校驗方法

實現stpInterface 調用處理這個接口方法

我們就是再把這個對象拿出來

// 根據用戶登錄ID和登錄類型返回不同的權限列表
UserInfo userInfo = (UserInfo) StpUtil.getSessionByLoginId(loginId).get((String) loginId);

然后找到權限 返回枚舉值

枚舉值要包裝成 list 類型

這邊返回的是List類型

這些文檔里都有...

package cn.hollis.nft.turbo.gateway.auth;import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import cn.hollis.nft.turbo.api.user.constant.UserPermission;
import cn.hollis.nft.turbo.api.user.constant.UserRole;
import cn.hollis.nft.turbo.api.user.constant.UserStateEnum;
import cn.hollis.nft.turbo.api.user.response.data.UserInfo;
import org.springframework.stereotype.Component;import java.util.List;/*** 自定義權限驗證接口實現類* StpInterface 接口用于自定義權限和角色的獲取邏輯。* StpInterfaceImpl 類實現了 StpInterface 接口,通過用戶的會話信息動態獲取用戶的權限和角色列表。* 在 Sa - Token 框架進行權限驗證時,會調用該類的方法來確定用戶是否具備相應的權限和角色。* 注意:這邊通過用戶會話信息動態獲取用戶權限和角色列表** @author Hollis*/
@Component
public class StpInterfaceImpl implements StpInterface {/*** 根據用戶的登錄 ID 和登錄類型獲取用戶的權限列表** @param loginId  用戶的登錄 ID* @param loginType 用戶的登錄類型* @return 用戶的權限列表,以字符串集合形式返回*/@Overridepublic List<String> getPermissionList(Object loginId, String loginType) {// 從會話中根據登錄 ID 獲取用戶信息UserInfo userInfo = (UserInfo) StpUtil.getSessionByLoginId(loginId).get((String) loginId);// 如果用戶角色是管理員,或者用戶狀態為激活狀態、已認證狀態if (userInfo.getUserRole() == UserRole.ADMIN|| userInfo.getState().equals(UserStateEnum.ACTIVE.name())|| userInfo.getState().equals(UserStateEnum.AUTH.name()) ) {// 賦予用戶基礎權限和認證權限return List.of(UserPermission.BASIC.name(), UserPermission.AUTH.name());}// 如果用戶狀態為初始狀態if (userInfo.getState().equals(UserStateEnum.INIT.name())) {// 賦予用戶基礎權限return List.of(UserPermission.BASIC.name());}// 如果用戶狀態為凍結狀態if (userInfo.getState().equals(UserStateEnum.FROZEN.name())) {// 賦予用戶凍結權限return List.of(UserPermission.FROZEN.name());}// 其他情況,賦予用戶無權限return List.of(UserPermission.NONE.name());}/*** 根據用戶的登錄 ID 和登錄類型獲取用戶的角色列表** @param loginId  用戶的登錄 ID* @param loginType 用戶的登錄類型* @return 用戶的角色列表,以字符串集合形式返回*/@Overridepublic List<String> getRoleList(Object loginId, String loginType) {// 從會話中根據登錄 ID 獲取用戶信息UserInfo userInfo = (UserInfo) StpUtil.getSessionByLoginId(loginId).get((String) loginId);// 如果用戶角色是管理員if (userInfo.getUserRole() == UserRole.ADMIN) {// 返回管理員角色return List.of(UserRole.ADMIN.name());}// 其他情況,返回普通用戶角色return List.of(UserRole.CUSTOMER.name());}
}

最后進行要進行 satoken 過濾器全局配置

SaReactorFilter

package cn.hollis.nft.turbo.gateway.auth;import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hollis.nft.turbo.api.user.constant.UserPermission;
import cn.hollis.nft.turbo.api.user.constant.UserRole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** sa-token的全局配置類,用于配置鑒權過濾器和異常處理邏輯** @author Hollis*/
@Configuration
@Slf4j
public class SaTokenConfigure {/*** 創建并配置 SaReactorFilter 實例,該過濾器用于對請求進行鑒權和異常處理** @return 配置好的 SaReactorFilter 實例*/@Beanpublic SaReactorFilter getSaReactorFilter() {return new SaReactorFilter()// 配置需要攔截的請求地址,/** 表示攔截所有請求.addInclude("/**")// 配置不需要攔截的請求地址,這里排除了網站圖標請求.addExclude("/favicon.ico")// 設置鑒權方法,每次請求進入時會執行該方法進行鑒權.setAuth(obj -> {// 登錄校驗:攔截所有路由,但排除指定的開放路由,對其他請求進行登錄狀態檢查SaRouter.match("/**").notMatch("/auth/**", "/collection/collectionList", "/collection/collectionInfo", "/wxPay/**").check(r -> StpUtil.checkLogin());// 權限認證:針對不同模塊的請求,校驗不同的權限// 管理界面請求需要用戶具備管理員角色SaRouter.match("/admin/**", r -> StpUtil.checkRole(UserRole.ADMIN.name()));// 下單界面請求需要用戶具備實名認證權限SaRouter.match("/trade/**", r -> StpUtil.checkPermission(UserPermission.AUTH.name()));// 用戶界面請求需要用戶具備基本權限或凍結權限SaRouter.match("/user/**", r -> StpUtil.checkPermissionOr(UserPermission.BASIC.name(), UserPermission.FROZEN.name()));// 商品界面請求需要用戶具備基本權限或凍結權限SaRouter.match("/order/**", r -> StpUtil.checkPermissionOr(UserPermission.BASIC.name(),UserPermission.FROZEN.name()));})// 設置異常處理方法,當鑒權方法拋出異常時會進入該方法進行處理.setError(this::getSaResult);}/*** 根據不同的異常類型,返回相應的錯誤信息** @param throwable 捕獲到的異常對象* @return 封裝了錯誤信息的 SaResult 對象*/private SaResult getSaResult(Throwable throwable) {switch (throwable) {// 處理用戶未登錄異常case NotLoginException notLoginException:// 記錄錯誤日志log.error("請先登錄");// 返回未登錄的錯誤信息return SaResult.error("請先登錄");// 處理用戶角色不匹配異常case NotRoleException notRoleException:// 判斷是否是管理員角色權限問題if (UserRole.ADMIN.name().equals(notRoleException.getRole())) {// 記錄越權使用的錯誤日志log.error("請勿越權使用!");// 返回越權使用的錯誤信息return SaResult.error("請勿越權使用!");}// 記錄無權限操作的錯誤日志log.error("您無權限進行此操作!");// 返回無權限操作的錯誤信息return SaResult.error("您無權限進行此操作!");// 處理用戶權限不足異常case NotPermissionException notPermissionException:// 判斷是否是實名認證權限問題if (UserPermission.AUTH.name().equals(notPermissionException.getPermission())) {// 記錄需要實名認證的錯誤日志log.error("請先完成實名認證!");// 返回需要實名認證的錯誤信息return SaResult.error("請先完成實名認證!");}// 記錄無權限操作的錯誤日志log.error("您無權限進行此操作!");// 返回無權限操作的錯誤信息return SaResult.error("您無權限進行此操作!");// 處理其他未知異常default:// 返回異常的錯誤信息return SaResult.error(throwable.getMessage());}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82715.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82715.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82715.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Cloud Gateway 中自定義驗證碼接口返回 404 的排查與解決

Spring Cloud Gateway 中自定義驗證碼接口返回 404 的排查與解決 問題背景 在一個基于 Spring Cloud Gateway WebFlux 構建的微服務項目中&#xff0c;新增了一個本地驗證碼接口 /code&#xff0c;使用函數式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…

Dify中聊天助手、agent、文本生成、chatflow、工作流模式解讀分析與對比

一次解讀 1. 聊天助手 (Chat Assistant) 情景定位 (Situation): 你需要創建一個可以與用戶進行多輪對話的AI應用&#xff0c;例如客服機器人、信息查詢助手、或一個特定領域的虛擬專家。目標明確 (Purpose): 核心目標是理解并響應用戶的連續提問&#xff0c;維持對話的上下文…

使用Node.js分片上傳大文件到阿里云OSS

阿里云OSS的分片上傳&#xff08;Multipart Upload&#xff09;是一種針對大文件優化的上傳方式&#xff0c;其核心流程和關鍵特性如下&#xff1a; 1. ?核心流程? 分片上傳分為三個步驟&#xff1a; 初始化任務?&#xff1a;調用InitiateMultipartUpload接口創建上傳任務…

C++ if語句完全指南:從基礎到工程實踐

一、選擇結構在程序設計中的核心地位 程序流程控制如同城市交通網絡&#xff0c;if語句則是這個網絡中的決策樞紐。根據ISO C標準&#xff0c;選擇結構占典型項目代碼量的32%-47%&#xff0c;其正確使用直接影響程序的&#xff1a; 邏輯正確性 執行效率 可維護性 安全邊界 …

【大模型LLM學習】Flash-Attention的學習記錄

【大模型LLM學習】Flash-Attention的學習記錄 0. 前言1. flash-attention原理簡述2. 從softmax到online softmax2.1 safe-softmax2.2 3-pass safe softmax2.3 Online softmax2.4 Flash-attention2.5 Flash-attention tiling 0. 前言 Flash Attention可以節約模型訓練和推理時間…

python打卡day46@浙大疏錦行

知識點回顧&#xff1a; 不同CNN層的特征圖&#xff1a;不同通道的特征圖什么是注意力&#xff1a;注意力家族&#xff0c;類似于動物園&#xff0c;都是不同的模塊&#xff0c;好不好試了才知道。通道注意力&#xff1a;模型的定義和插入的位置通道注意力后的特征圖和熱力圖 內…

JavaSec-SPEL - 表達式注入

簡介 SPEL(Spring Expression Language)&#xff1a;SPEL是Spring表達式語言&#xff0c;允許在運行時動態查詢和操作對象屬性、調用方法等&#xff0c;類似于Struts2中的OGNL表達式。當參數未經過濾時&#xff0c;攻擊者可以注入惡意的SPEL表達式&#xff0c;從而執行任意代碼…

SpringCloud——OpenFeign

概述&#xff1a; OpenFeign是基于Spring的聲明式調用的HTTP客戶端&#xff0c;大大簡化了編寫Web服務客戶端的過程&#xff0c;用于快速構建http請求調用其他服務模塊。同時也是spring cloud默認選擇的服務通信工具。 使用方法&#xff1a; RestTemplate手動構建: // 帶查詢…

【深入學習Linux】System V共享內存

目錄 前言 一、共享內存是什么&#xff1f; 共享內存實現原理 共享內存細節理解 二、接口認識 1.shmget函數——申請共享內存 2.ftok函數——生成key值 再次理解ftok和shmget 1&#xff09;key與shmid的區別與聯系 2&#xff09;再理解key 3&#xff09;通過指令查看/釋放系統中…

探索 Java 垃圾收集:對象存活判定、回收流程與內存策略

個人主頁-愛因斯晨 文章專欄-JAVA學習筆記 熱門文章-賽博算命 一、引言 在 Java 技術體系里&#xff0c;垃圾收集器&#xff08;Garbage Collection&#xff0c;GC&#xff09;與內存分配策略是自動內存管理的核心支撐。深入探究其原理與機制&#xff0c;對優化程序內存性能…

hbase資源和數據權限控制

hbase適合大數據量下點查 https://zhuanlan.zhihu.com/p/471133280 HBase支持對User、NameSpace和Table進行請求數和流量配額限制&#xff0c;限制頻率可以按sec、min、hour、day 對于請求大小限制示例&#xff08;5K/sec,10M/min等&#xff09;&#xff0c;請求大小限制單位如…

大數據-275 Spark MLib - 基礎介紹 機器學習算法 集成學習 隨機森林 Bagging Boosting

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; 大模型篇章已經開始&#xff01; 目前已經更新到了第 22 篇&#xff1a;大語言模型 22 - MCP 自動操作 FigmaCursor 自動設計原型 Java篇開…

Delphi 實現遠程連接 Access 數據庫的指南

方法一&#xff1a;通過局域網共享 Access 文件&#xff08;簡單但有限&#xff09; 步驟 1&#xff1a;共享 Access 數據庫 將 .mdb 或 .accdb 文件放在局域網內某臺電腦的共享文件夾中。 右鍵文件夾 → 屬性 → 共享 → 啟用共享并設置權限&#xff08;需允許網絡用戶讀寫&a…

VR視頻制作有哪些流程?

VR視頻制作流程知識 VR視頻制作&#xff0c;作為融合了創意與技術的復雜制作過程&#xff0c;涵蓋從初步策劃到最終呈現的多個環節。在這個過程中&#xff0c;我們可以結合眾趣科技的產品&#xff0c;解析每一環節的實現與優化&#xff0c;揭示背后的奧秘。 VR視頻制作有哪些…

文件上傳/下載接口開發

接口特性 文件傳輸接口與傳統接口的核心差異體現在數據傳輸格式&#xff1a; 上傳接口采用 multipart/form-data 格式支持二進制文件傳輸下載接口接收二進制流并實現本地文件存儲 文件上傳接口開發 接口規范 請求地址&#xff1a;/createbyfile 請求方式&#xff1a;POST…

深入學習RabbitMQ隊列的知識

目錄 1、AMQP協議 1.1、介紹 1.2、AMQP的特點 1.3、工作流程 1.4、消息模型 1.5、消息結構 1.6、AMQP 的交換器類型 2、RabbitMQ結構介紹 2.1、核心組件 2.2、最大特點 2.3、工作原理 3、消息可靠性保障 3.1、生產端可靠性 1、生產者確認機制 2、持久化消息 3.…

【計算機網絡】NAT、代理服務器、內網穿透、內網打洞、局域網中交換機

&#x1f525;個人主頁&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收錄專欄&#x1f308;&#xff1a;計算機網絡 &#x1f339;往期回顧&#x1f339;&#xff1a;【計算機網絡】數據鏈路層——ARP協議 &#x1f516;流水不爭&#xff0c;爭的是滔滔不息 一、網絡地址轉…

[論文閱讀] 人工智能 | 大語言模型計劃生成的新范式:基于過程挖掘的技能學習

#論文閱讀# 大語言模型計劃生成的新范式&#xff1a;基于過程挖掘的技能學習 論文信息 Skill Learning Using Process Mining for Large Language Model Plan Generation Andrei Cosmin Redis, Mohammadreza Fani Sani, Bahram Zarrin, Andrea Burattin Cite as: arXiv:2410.…

C文件操作2

五、文件的隨機讀寫 這些函數都需要包含頭文件 #include<stdio.h> 5.1 fseek 根據文件指針的位置和偏移量來定位文件指針&#xff08;文件內容的光標&#xff09; &#xff08;重新定位流位置指示器&#xff09; int fseek ( FILE * stream, long int offset, int or…

react私有樣式處理

react私有樣式處理 Nav.jsx Menu.jsx vue中通過scoped來實現樣式私有化。加上scoped&#xff0c;就屬于當前組件的私有樣式。 給視圖中的元素都加了一個屬性data-v-xxx&#xff0c;然后給這些樣式都加上屬性選擇器。&#xff08;deep就是不加屬性也不加屬性選擇器&#xff09; …