在微服务架构中,通过 Spring Cloud Gateway 集成 JWT 鉴权的最推荐方案是在网关层实现自定义全局过滤器(GlobalFilter),拦截请求头中的 Token 并验证签名,验证通过后转发至下游服务。
先说结论:Gateway 统一鉴权适合 Stateless 微服务架构,能解决 Session 共享和代码冗余问题,但需重点管理密钥安全和公共路径豁免。
- 适合:多微服务需要统一登录态、跨域认证、无状态扩展的场景。
- 先准备:引入 Spring Cloud Gateway 和 JWT 处理库(如 jjwt),规划好密钥存储方式。
- 验收:未携带 Token 请求返回 401,携带有效 Token 请求返回 200 且下游能获取用户信息。
命令速用版
网关鉴权主要通过代码配置实现,以下是核心依赖和过滤器逻辑的快速参考片段。
<!-- Maven 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>// 自定义全局过滤器核心逻辑
public class JwtAuthFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (!JwtUtil.validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
} 为什么会这样
微服务架构下每个服务独立认证会导致代码冗余和 Session 共享困难,网关统一鉴权能集中管理安全逻辑。
传统单体应用的 Session 认证在分布式环境中需要 Redis 共享 Session,增加了系统复杂度和性能开销。JWT 基于数字签名,服务端无需存储状态,适合水平扩展。将认证逻辑下沉到网关层,后端微服务只需关注业务逻辑,避免了每个服务重复编写验证代码,同时也降低了因认证逻辑不一致导致的安全漏洞风险。
分步处理
实施 Gateway 统一 JWT 鉴权需按依赖引入、路由配置、过滤器开发、白名单设置的顺序进行。
1. 引入核心依赖
在网关服务的 pom.xml 中添加 Spring Cloud Gateway 和 JWT 处理库依赖,确保版本兼容。
2. 配置路由规则
在 application.yml 中定义路由,将外部请求映射到具体微服务,例如将/api/user/** 路由到 user-service。
3. 实现全局过滤器
创建实现 GlobalFilter 接口的类,在 filter 方法中获取请求头 Authorization 字段,调用工具类验证 Token 有效性。
4. 设置白名单路径
在过滤器逻辑中增加判断,对登录接口、静态资源等公共路径(如/api/users/public/**)跳过鉴权,直接放行。
5. 传递用户信息
验证通过后,从 JWT 解析用户 ID 或角色,放入请求头(如 X-User-Id)传递给下游服务,避免下游重复解析。
怎么验证是否生效
通过 curl 命令模拟携带和不携带 Token 的请求,观察 HTTP 状态码和下游服务日志。
1. 验证未授权拦截
执行 curl 请求不带 Authorization 头,预期网关直接返回 401 Unauthorized,请求不应到达下游服务。
2. 验证授权通过
执行 curl 请求携带有效 Bearer Token,预期返回 200 OK,且下游服务日志中能打印出传递的用户 ID 信息。
3. 验证白名单放行
访问配置的公共路径(如登录接口),不带 Token 也应返回 200 或具体的业务响应,不被网关拦截。
常见坑
配置过程中容易忽略公共路径豁免、密钥硬编码和时钟同步问题,导致服务不可用或安全风险。
1. 公共路径未豁免
登录接口本身不需要鉴权,若未配置跳过逻辑,会导致用户无法获取 Token,形成死循环。
2. 密钥管理不当
签名密钥硬编码在代码中或提交到版本控制,一旦泄露所有 Token 均可伪造,建议使用配置中心或环境变量管理。
3. 时间不同步
JWT 验证依赖时间戳,若网关服务器与认证服务器时间偏差过大,会导致 Token 被误判为过期或无效。
常见问题
JWT 鉴权如何实现用户注销?
JWT 本身无状态无法主动失效,需结合 Redis 黑名单机制,注销时将 Token 存入 Redis 并设置过期时间,网关验证时检查黑名单。
Gateway 鉴权会影响接口性能吗?
会有轻微开销,主要是签名验证和解析耗时,但相比每个服务独立查询数据库验证 Session,网关统一鉴权整体性能更优。
Token 应该存放在客户端哪里?
建议存放在 HttpOnly 的 Cookie 中以防 XSS 攻击,或存放在 LocalStorage 中但需配合 CSRF 防护,避免存放在易被脚本读取的位置。
参考来源
- 微服务架构下的统一安全入口:Gateway JWT 认证实战指南
- Gateway 集成 JWT 身份认证:微服务统一认证的实战指南 - 详解
- 微服务网关鉴权全解析:从 Gateway 到 JWT 的安全实践 - 百度开发者中心
- SpringCloud 搭建微服务之 Gateway+Jwt 实现统一鉴权
- 微服务网关鉴权:gateway 使用、网关限流使用 用户密码加密 JWT 鉴权