springcloud/springmvc協調作用傳遞驗證信息

微服務架構的拆分,各模塊之間使用feign組件來進行相互http轉發通信。

前端與后端之間使用springcloud的網關來進行協調。

現在問題出現,用戶的信息如何進行傳遞?

前端請求攜帶請求頭,請求頭中的authorization為攜帶的對應token,這個token如何轉發給各個微服務模塊?

具體流程:前端發送請求->網關進行解析->從springcloud攔截器的exchange.header中解析出token->將token寫入到新的exchange.header中,并且命名為info,這個exchange會被向后傳遞(因為本身springcloud就有多個攔截器,該攔截器處理完之后會傳遞給下一個攔截器 )->根據網關解析的端口號,發送request到對應端口的微服務中->微服務的攔截器對request進行攔截(實際上是一個共有模塊,各個微服務依賴于這個模塊,所以其網絡請求會被該模塊攔截)->讀取傳遞過來請求頭中的info信息,存入threadLocal中。

1.由于所有前端請求都會到達springcloud的攔截器,并且攔截器有多個,只需在攔截器中將需要傳遞的“info”存進網絡請求中,對應的攔截器定義如下:

package com.hxy.hmgateway.filter;import com.hxy.hmgateway.config.AuthProperties;
import com.hxy.hmgateway.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.List;@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {private final AuthProperties authProperties;private final JwtTool jwtTool;private final AntPathMatcher antPathMatcher = new AntPathMatcher();@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();//放行排除路徑String path = request.getPath().toString();if(isExclude(path,authProperties.getExcludePaths())){return chain.filter(exchange);}//1.獲取tokenHttpHeaders headers = request.getHeaders();List<String> tokenList = headers.get("authorization");//2.判別token是否為空String token = null;if (tokenList!=null && !tokenList.isEmpty()){token = tokenList.get(0);}//3.獲取userIdLong userId = null;//4.判別token是否正確try {userId = jwtTool.parseToken(token);} catch (Exception e) {ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//TODO userId的轉發System.out.println("userId:"+userId);String userInfo = String.valueOf(userId);ServerWebExchange swe = exchange.mutate().request(builder ->builder.header("info", userInfo)).build();//5.放行return chain.filter(swe);}private boolean isExclude(String path, List<String> excludePaths) {for (String pathPattern : excludePaths) {if(antPathMatcher.match(pathPattern, path)) return true;}return false;}@Overridepublic int getOrder() {return 0;}
}

?注意這里的exchange.mutate指令用于將info存儲在網絡請求中。

2.該攔截器經過springcloud網關轉發后,首先到達所有微服務公共依賴的模塊,這個模塊會使用springmvc攔截器,用于攔截,info,并將其存入threadlocal中。代碼如下;

package com.hmall.common.intercepter;import com.hmall.common.utils.UserContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class UserInfoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String info = request.getHeader("info");if (info == null) return true;Long userId = Long.valueOf(info);UserContext.setUser(userId);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {UserContext.removeUser();}
}
package com.hmall.common.config;import com.hmall.common.intercepter.UserInfoInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());}
}

為了使得其余微服務能夠掃描到該共有模塊的包,需要將攔截器對應的包添加在如下文件中:

對應的spring.factories文件如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.hmall.common.config.MyBatisConfig,\com.hmall.common.config.MvcConfig,\com.hmall.common.config.JsonConfig

最后需要注意,在mvc配置文件中,添加了一個注解

ConditionalOnClass,用于標記僅對使用了該類的模塊生效

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

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

相關文章

Apache Flink Kafka 寫連接器源碼深度剖析

一、架構概述 Apache Flink 提供的 Kafka 寫入連接器是實現與 Kafka 消息隊列集成的關鍵組件&#xff0c;支持多種語義保證和靈活配置選項。本文將深入分析 Flink Kafka 寫入連接器的源碼實現&#xff0c;包括架構設計、核心類、事務機制和性能優化等方面。 1.1 整體架構 Fl…

強化學習理論基礎:從Q-learning到PPO的算法演進(2)

文章目錄 Policy gradient思想(REINFORCE算法)優勢函數PPO(Proximal Policy Optimization)Policy gradient思想(REINFORCE算法) 下面我們來探討一下Policy gradient策略,也就是REINFORCE算法。 在玩剪刀石頭布這個簡單的游戲中,我們可以有不同的策略。一種是完全隨機地…

Oracle數據庫文件變成32k故障恢復--惜分飛

最近一個客戶數據庫重啟系統之后,數據文件大小變為了32kb,我接手的不是第一現場(客戶那邊嘗試了rman還原操作),查看alert日志,數據庫最初報錯 Wed Jun 18 13:09:23 2025 alter database open Block change tracking file is current. Read of datafile D:\APP\ADMINISTRATOR\OR…

移動端 uniapp 寫一個可自由拖拽的小鍵盤

寫之前要考慮&#xff1a; 鍵盤展開后&#xff0c;不能超過手機邊緣在底部展開鍵盤&#xff0c;鍵盤應出現在展開按鈕上方&#xff1b;以此類推重復點擊展開按鈕&#xff0c;關閉鍵盤 效果&#xff1a; 代碼如下&#xff0c;有些按鍵邏輯還需要優化 <template><vi…

《二分枚舉答案(配合數據結構)》題集

文章目錄 1、模板題集2、課內題集3、課后題集1. 字符串哈希2. 并查集3. ST表 1、模板題集 分巧克力 2、課內題集 倒水 冶煉金屬 連續子序列的個數 3、課后題集 括號內的整數代表完整代碼行數。 1. 字符串哈希 你猜猜是啥題(60) 2. 并查集 拯救萌萌(72) 3. ST表 GCD不小…

PY32F030單片機,優勢替代ST GD,主頻48MHz,帶LED數碼管驅動

PY32F030是一款高性能32位單片機&#xff0c;采用ARM Cortex-M0內核&#xff0c;工作頻率高達48MHz&#xff0c;具備64KB Flash和8KB SRAM。它支持1.7V~5.5V寬電壓范圍&#xff0c;集成多路I2C、SPI、USART通訊外設&#xff0c;配備12位ADC、16位定時器和比較器&#xff0c;適用…

Rockchip Uboot中修改固件探測的存儲介質

Rockchip Uboot中修改固件探測的存儲介質 Rockchip uboot中支持從 eMMC、SDcard、NAND 、SPI_NAND、SPI_NOR等存儲介質引導固件。 uboot的spl啟動的時候會默認呢都會去探測這些介質&#xff0c;這樣會導致探測時間變長&#xff0c;在實際產品中可以根據產品需求進行個性化的配…

動手學Python:從零開始構建一個“文字冒險游戲”

動手學Python&#xff1a;從零開始構建一個“文字冒險游戲” 大家好&#xff0c;我是你的技術向導。今天&#xff0c;我們不聊高深的框架&#xff0c;也不談復雜的算法&#xff0c;我們來做一點“復古”又極具趣味性的事情——用Python親手打造一個屬于自己的文字冒險游戲&…

基于Kafka實現企業級大數據遷移的完整指南

在大數據時代&#xff0c;數據遷移已成為企業數字化轉型過程中的常見需求。本文將詳細介紹如何利用Kafka構建高可靠、高性能的大數據遷移管道&#xff0c;涵蓋從設計到實施的完整流程。 一、為什么選擇Kafka進行數據遷移&#xff1f; Kafka作為分布式消息系統&#xff0c;具有…

GEO引領品牌大模型種草:邁向Web3.0與元宇宙的認知新空間

在數字技術的演進歷程中&#xff0c;我們正經歷著從Web2.0到Web3.0、從平面互聯網到沉浸式元宇宙的范式轉變。這一轉變不僅重塑了數字空間的形態和交互方式&#xff0c;更深刻改變了品牌與用戶的連接模式和價值創造邏輯。而在這個新興的數字疆域中&#xff0c;生成式引擎優化&a…

【機器學習與數據挖掘實戰 | 醫療】案例18:基于Apriori算法的中醫證型關聯規則分析

【作者主頁】Francek Chen 【專欄介紹】 ? ? ?機器學習與數據挖掘實戰 ? ? ? 機器學習是人工智能的一個分支,專注于讓計算機系統通過數據學習和改進。它利用統計和計算方法,使模型能夠從數據中自動提取特征并做出預測或決策。數據挖掘則是從大型數據集中發現模式、關聯…

83、高級特性-自定義starter細節

83、高級特性-自定義starter細節 自定義Spring Boot Starter可以將通用功能封裝成可復用的模塊&#xff0c;簡化其他項目的配置和使用。以下是創建自定義Starter的詳細步驟和關鍵細節&#xff1a; ### 1. 項目結構 通常&#xff0c;自定義Starter包含兩個模塊&#xff1a; ####…

專注推理查詢(ARQs):一種提升大型語言模型指令遵循度、決策準確性和防止幻覺的結構化方法

大型語言模型&#xff08;LLMs&#xff09;在客戶服務、自動化內容創作和數據檢索方面變得至關重要。然而&#xff0c;它們的有效性常常因其在多次交互中無法始終如一地遵循詳細指令而受到限制。在金融服務和客戶支持系統等高風險環境中&#xff0c;嚴格遵循指南是必不可少的&a…

華為云Flexus+DeepSeek征文 | DeepSeek驅動的醫療AI Agent:智能問診系統開發完整指南

華為云FlexusDeepSeek征文 | DeepSeek驅動的醫療AI Agent&#xff1a;智能問診系統開發完整指南 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 總有一行代碼&#xff0c;能點亮萬千星辰。 &#x1f50d; 在技術的宇宙中&#xff0c;我愿做永不停歇…

【大模型水印論文閱讀2】前綴文本編碼、均勻性約束

TOC &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f680; 感謝你的陪伴與支持~ 歡迎添加文末好友 &#x1f30c; 在所有感興趣的領域擴展知識&#xff0c;不定期掉落福利資訊(*^▽^*) 寫在最前面 版權聲明&#xff1a;本文為原創&#xff0c;遵循 CC 4.0 BY-SA 協議。…

破繭時刻,與光同行

凌晨五點的鬧鐘刺破薄霧&#xff0c;我摸黑打開臺燈。攤開的數學錯題本上&#xff0c;函數圖像在暖黃的光暈里舒展&#xff0c;像等待破譯的密碼。這樣的清晨已持續三百多個日夜&#xff0c;我知道&#xff0c;在無數個相似的時刻里&#xff0c;總有千萬盞臺燈在黑暗中次第亮起…

Learning PostgresSQL讀書筆記: 第8章 Triggers and Rules

本章將討論以下內容&#xff1a; ? 探索 PostgreSQL 中的規則 ? 管理 PostgreSQL 中的觸發器 ? 事件觸發器 探索 PostgreSQL 中的規則 文檔中的這段話闡述了rule和trigger的區別&#xff1a; PostgreSQL 規則系統允許定義在數據庫表中插入、更新或刪除時執行的替代操作。粗…

信創國產化替代中的開發語言選擇分析

在信息技術應用創新(信創)國產化替代過程中&#xff0c;選擇合適的開發語言至關重要。以下是適合信創環境的開發語言及其優勢分析&#xff1a; 主流適合信創的編程語言 1. Java 優勢&#xff1a;跨平臺特性(JVM)、豐富的生態體系、企業級應用成熟 信創適配&#xff1a;國內有…

Android 中 函數實現多個返回值的幾種方式

在編程中&#xff0c;函數通常只能返回一個值。但通過使用對象封裝、Pair、Triple、數組、列表或 Bundle 方式&#xff0c;可以輕松地返回多個值。 1、對象封裝方式 創建數據類來封裝需要返回的多個值。 data class Result(val code: Int, val message: String)fun getMultiV…

Leetcode百題斬-DP

又到了最好玩的dp了&#xff0c;各種玄學轉移也算是其樂無窮。前段時間剛做的LCA正是這種題的小試牛刀&#xff0c;如果當時就把這個專題刷完了&#xff0c;或許我現在已經從西溪園區跑到云谷園區了。 不過&#xff0c;恐怖如斯的dp專題居然只給了一道hard&#xff0c;基本也沒…