实战!openFeign如何实现全链路JWT令牌信息不丢失?

开发 前端
令牌中继通俗的讲则是让令牌在微服务链路调用中传递下去,保证各个微服务能够获取令牌中的用户信息。

今天这篇文章介绍一下JWT令牌如何在微服务链路中保证信息不丢失?官方称为令牌中继。

什么是令牌中继?

令牌中继通俗的讲则是让令牌在微服务链路调用中传递下去,保证各个微服务能够获取令牌中的用户信息。

以下订单的例子来说,如下图:

下单流程

客户端携带令牌请求网关,网关鉴权成功后会将令牌中的用户信息解析出来放在请求头中下发给订单服务,同样的,订单服务需要将用户信息传递给账户服务获取该用户的账户信息。

那么问题来了?如何保证网关服务->订单服务->账户服务这条链路中的用户信息传递下去是个痛点

解决方案

令牌在openFeign调用过程中是不能自动中继的,因此必须手动的将令牌信息传递下去。

注意:openFeign在开启熔断降级后内部调用开启了子线程,因此传统的方案直接在RequestInterceptor中设置是不可行的。

那么如何保证子线程也能获取请求头中的用户信息呢?

答案是:RequestContextHolder这个神器。

RequestContextHolder内部通过InheritableThreadLocal实现子线程共享信息。

在FeignCircuitBreakerInvocationHandler这个类中也是有如下一行代码:

RequestContextHolder.setRequestAttributes(requestAttributes); 



正是使用RequestContextHolder将request的信息保存在其中,因此实现令牌中继只需要读取RequestContextHolder的信息即可。

详细代码如下:

/**  * @author 公众号:码猿技术专栏  * 用于实现令牌信息中继  */ @Component public class FeignRequestInterceptor implements RequestInterceptor {     @Override     public void apply(RequestTemplate template) {         //从RequestContextHolder中获取HttpServletRequest         HttpServletRequest httpServletRequest = RequestContextUtils.getRequest();         //获取RequestContextHolder中的信息         Map<String, String> headers = getHeaders(httpServletRequest);         //放入feign的RequestTemplate中         for (Map.Entry<String, String> entry : headers.entrySet()) {             template.header(entry.getKey(), entry.getValue());         }     }      /**      * 获取原请求头      */     private Map<String, String> getHeaders(HttpServletRequest request) {         Map<String, String> map = new LinkedHashMap<>();         Enumeration<String> enumeration = request.getHeaderNames();         if (enumeration != null) {             while (enumeration.hasMoreElements()) {                 String key = enumeration.nextElement();                 String value = request.getHeader(key);                 map.put(key, value);             }         }         return map;     } } 



源码目录如下图:


责任编辑:武晓燕 来源: 码猿技术专栏
相关推荐

2023-11-14 09:04:15

用户节点不可用

2023-01-30 22:34:44

Node.js前端

2021-10-22 09:00:59

令牌JWT

2021-12-30 08:13:00

JWT登录令牌

2023-11-21 09:35:49

全量部署微服务

2023-06-01 08:54:08

RabbitMQ确认机制生产端

2024-01-05 00:29:36

全链路灰度发布云原生

2022-08-31 22:25:53

微服务架构DevOPs

2022-02-15 17:56:19

SpringBoot日志

2022-12-28 09:07:41

2023-11-13 10:41:44

Spring微服务

2023-10-16 23:43:52

云原生可观测性

2022-05-23 08:23:24

链路追踪SleuthSpring

2023-03-02 09:17:50

全链路监控系统

2022-01-04 17:08:02

全链路观测平台

2022-07-22 07:59:17

日志方案

2022-04-27 10:53:34

web优化性能

2024-03-13 08:56:17

全链路压力测试

2024-02-26 08:10:00

Redis数据数据库

2023-10-30 07:25:37

数据湖数据处理
点赞
收藏

51CTO技术栈公众号