Spring Cloud Gateway 统一校验 JWT 令牌合法性最推荐的方式是实现自定义 GlobalFilter 过滤器,在请求路由到微服务之前拦截并解析 Token。适用场景为前后端分离架构下的集中式鉴权,风险边界在于需排除登录接口和静态资源,避免死循环或阻断正常访问。
先说结论:通过自定义 GlobalFilter 拦截请求头中的 Authorization 字段,使用 Java JWT 库验证签名和有效期,验证失败直接返回 401 状态码。
- 先判断:微服务架构入口统一鉴权、前后端分离项目、需要集中管理令牌失效策略的场景
- 优先做:配置白名单路径放过登录注册接口、确保网关与认证服务时钟同步、密钥配置使用环境变量
- 再验证:使用 curl 携带非法 Token 请求接口、检查网关日志是否记录鉴权失败、确认下游服务未收到无效请求
命令速用版
无需系统命令,核心是添加依赖和编写过滤器类。Maven 依赖如下:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>为什么会这样
网关作为流量入口,在此处校验能避免无效请求穿透到内部服务,降低后端压力。Spring Cloud Gateway 基于 WebFlux 响应式栈,GlobalFilter 链式调用机制允许在路由前修改请求或终止请求,是实现统一鉴权的天然位置。
分步处理
第一步:创建实现 GlobalFilter 和 Ordered 接口的类。在 filter 方法中获取 ServerWebExchange 请求对象,从 Header 中读取 Authorization 字段。
第二步:判断 Token 格式是否正确,通常以 Bearer 开头。调用 JWT 解析库验证签名密钥和 exp 过期时间。如果验证抛出异常,设置响应状态为 401 并结束请求。
第三步:验证通过后,可将解析出的用户信息放入 Request Header 或 Exchange 属性中,传递给下游微服务。最后调用 chain.filter(exchange) 放行请求。
第四步:配置白名单。在过滤器逻辑开头判断请求路径,如果是登录、注册、Swagger 文档等路径,直接放行不调用校验逻辑。
怎么验证是否生效
使用 curl 命令发送不带 Token 的请求,预期返回 401 Unauthorized。发送带过期 Token 的请求,预期同样返回 401。发送有效 Token 请求,预期返回下游服务的正常业务数据。检查网关日志,确认鉴权过滤器的打印信息是否符合预期。
常见坑
跨域预检请求 OPTIONS 可能被拦截导致前端报错,需在过滤器中放行 OPTIONS 方法。密钥硬编码在代码中存在泄露风险,应通过配置中心或环境变量注入。Token 解析异常未捕获会导致网关直接返回 500 而不是 401,需捕获 Specific Exception。
常见问题
网关校验 JWT 会影响性能吗?
会有轻微影响,但通常可接受。JWT 验证主要是本地 CPU 计算签名,不涉及远程数据库查询,单次验证耗时通常在毫秒级,公开资料中没有看到可靠的量化数据表明会成为瓶颈。
微服务内部调用还需要校验吗?
不需要重复校验。网关校验通过后,通常会将用户信息透传给内部服务,内部服务信任网关传来的身份标识,除非涉及服务间高安全级别调用。
Token 刷新怎么处理?
网关只负责校验有效性,不负责刷新。刷新逻辑应由认证服务提供独立接口,客户端 Token 过期后调用刷新接口获取新 Token,网关不拦截刷新接口的请求。