You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Spring实现网关层不透明令牌与JWT映射的微服务认证授权方案

(本项目为大学课程项目,安全性要求略低于真实生产环境,仅实现API无前端部分)

实现方案

你需要的「对外返回不透明令牌、内部微服务间用JWT交互」的模式核心逻辑为:用户登录时认证中心生成不透明随机字符串和对应绑定的JWT,存入共享存储后仅对外返回不透明令牌;网关收到用户携带不透明令牌的请求后,查存储取出对应JWT透传给下游,下游直接本地校验JWT即可,无需额外请求依赖。

1. 认证中心实现

  • 用户登录校验账号密码通过后,生成两类令牌:
    • 不透明令牌:直接用UUID.randomUUID().toString().replace("-","")生成32位随机字符串即可,过期时间和绑定的JWT保持一致
    • 标准JWT:写入用户ID、权限、角色等业务需要的声明,推荐用RSA256非对称算法签名,完全规避JWT被篡改的风险;课程项目简化也可以用HS256对称签名,只要保证密钥不对外泄露即可
  • 将「不透明令牌 -> JWT」的映射关系写入Redis,设置和JWT一致的过期时间,无需持久化,数据丢失最多触发用户重新登录
  • 登录接口仅返回不透明令牌给调用端,不返回JWT任何内容

2. Spring Cloud Gateway 令牌转换逻辑实现

自定义全局过滤器,优先级设置在路由转发之前,核心逻辑为提取用户传的不透明令牌,替换成对应JWT后透传给下游,核心代码示例如下:

@Component
public class TokenTranslateFilter implements GlobalFilter, Ordered {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private static final String AUTH_HEADER = "Authorization";
    private static final String BEARER_PREFIX = "Bearer ";
    private static final String TOKEN_KEY_PREFIX = "opaque_token:";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String authHeader = request.getHeaders().getFirst(AUTH_HEADER);
        // 校验是否携带合法Bearer令牌
        if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        String opaqueToken = authHeader.substring(BEARER_PREFIX.length());
        String jwt = stringRedisTemplate.opsForValue().get(TOKEN_KEY_PREFIX + opaqueToken);
        if (jwt == null) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        // 替换请求头为内部用JWT
        ServerHttpRequest newRequest = request.mutate()
                .header(AUTH_HEADER, BEARER_PREFIX + jwt)
                .build();
        return chain.filter(exchange.mutate().request(newRequest).build());
    }

    @Override
    public int getOrder() {
        // 优先级设为最高,在所有路由逻辑之前执行
        return -100;
    }
}

3. 下游微服务JWT校验实现

  • 所有内部微服务统一引入spring-boot-starter-oauth2-resource-server依赖
  • 配置文件里指定JWT的验签公钥(HS256则配置对称密钥),不需要连接Redis也不需要调用认证中心,直接本地校验JWT签名和过期时间即可
  • 业务逻辑直接从Spring Security上下文获取用户权限、ID等信息即可,和直接用JWT的开发逻辑完全一致,无需额外适配

课程项目简化优化点

  • 不需要搭建专业认证中心,直接写独立的用户服务实现登录和令牌生成逻辑即可
  • 如果不想部署Redis,可改用Caffeine本地缓存存储令牌映射,只要网关是单实例部署就完全可用,开发调试更简单

内容的提问来源于stack exchange,提问作者Jose Carlos Padilla Cancio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:24:00