微服务架构的拆分,各模块之间使用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;基本也没…