如何在Spring Cloud Gateway中从AccessToken提取UserId并改写路径传递给下游服务
解决Spring Cloud Gateway过滤器执行顺序与URL改写问题
核心问题是过滤器执行顺序错位,你需要让提取userId的过滤器拥有比URL改写过滤器更高的优先级(更小的order值)——Spring Cloud Gateway中过滤器的执行顺序由order数值决定,数值越小越先执行。
步骤1:自定义提取userId的过滤器,设置高优先级
创建自定义GatewayFilterFactory,负责解析AccessToken中的userId并存储到请求上下文:
import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.core.Ordered; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; @Component public class ExtractUserIdGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> { // 设置优先级,确保比URL改写过滤器先执行(默认RewritePath的order为LOWEST_PRECEDENCE-1) @Override public int getOrder() { return 1; } @Override public GatewayFilter apply(Object config) { return (exchange, chain) -> { // 从Authorization头获取AccessToken,前缀为Bearer String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION); if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); // 替换为你的实际Token解析逻辑(比如JWT解析) String userId = parseUserIdFromToken(token); // 将userId存入请求上下文,供后续过滤器调用 exchange.getAttributes().put("userId", userId); } return chain.filter(exchange); }; } // 示例解析方法,根据你的Token类型实现 private String parseUserIdFromToken(String token) { // 这里写Token解析逻辑,比如从JWT的claim中提取userId return "123456"; // 模拟返回userId } }
步骤2:配置路由,使用存储的userId改写URL
在application.yml中配置路由,通过${attribute.userId}引用上下文存储的userId,同时确保自定义过滤器先执行:
spring: cloud: gateway: routes: - id: customer-info-route uri: http://your-downstream-service predicates: - Path=/api/customer-info/** filters: # 先执行自定义提取userId的过滤器 - ExtractUserId # 再执行URL改写,用上下文的userId替换路径变量 - RewritePath=/api/customer-info/(?<segment>.*), /api/customer-info/${attribute.userId}
关键注意事项
- 默认
RewritePathGatewayFilterFactory的执行顺序是Ordered.LOWEST_PRECEDENCE - 1(即2147483646),自定义过滤器的order值只要小于这个数,就能优先执行。 - 如果使用全局过滤器(GlobalFilter),同样需要实现
Ordered接口并设置合适的order值。 - 需添加Token解析失败的异常处理(比如Token无效、不存在时返回401响应),避免下游服务收到无效请求。
内容的提问来源于stack exchange,提问作者Murad Zulfugarov
相关产品推荐
相关产品推荐

