微服务统一认证:JWT+网关全局鉴权体系
微服务统一认证JWT网关全局鉴权体系每个微服务都自己搞一套登录校验——这跟每个房间都装一把不同的锁有什么区别用户得带一大串钥匙。今天用 JWT 网关搞一套全局鉴权一锁通所有。一、微服务认证方案的演进单体应用时代用户登录后服务器在 Session 里存状态客户端带个 Cookie 就行。微服务化后这个模式碰到了问题Session Cookie 的困境 ┌─ order-service ─┐ 用户 ←→ 浏览器 ←→ 网关 ├─ product-service├ 谁都不认识谁的 Session └─ user-service ──┘ 问题1Session 存在单机内存其他服务访问不到 问题2即使共享 Redis Session跨域 Cookie 也是个坑 问题3服务间调用时下游不知道上游的用户身份1.1 三种方案对比方案原理优点缺点Session Cookie服务端存状态Cookie 传 sessionId可控性强、可主动踢人不适合分布式、跨域困难JWT推荐客户端存 Token自包含用户信息无状态、跨域友好、适合微服务无法主动失效、Token 体积大OAuth2第三方授权资源服务器分离适合开放平台复杂度高、学习曲线陡JWT 在微服务场景的优势无状态不需要集中式 Session 存储Token 本身就携带用户信息任何服务拿到 Token 都能独立校验。二、JWT 原理拆解JWTJSON Web Token长这样eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsInJvbGUiOiJhZG1pbiJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 拆开来看就是三段 Base64 编码用点号连接┌──────────────────────┬──────────────────────────┬─────────────────────────┐ │ Header │ Payload │ Signature │ ├──────────────────────┼──────────────────────────┼─────────────────────────┤ │ { │ { │ HMACSHA256( │ │ alg: HS256, │ userId: 1, │ base64(header) │ │ typ: JWT │ role: admin, │ . │ │ } │ exp: 1699999999 │ base64(payload), │ │ │ } │ secret │ │ │ │ ) │ └──────────────────────┴──────────────────────────┴─────────────────────────┘Header声明算法和类型HS256 HMAC-SHA256Payload存放声明claims比如用户 ID、角色、过期时间。Payload 只是 Base64 编码不是加密千万别放密码进去。Signature用 Header Payload 密钥算出签名防篡改。任何人改了 Payload签名就对不上了。校验流程服务器收到 JWT → 用同样的算法对 HeaderPayload 算签名 → 对比 Signature → 一致则信任 Payload。三、JWT 生成与解析jjwt引入 jjwt 库dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-api/artifactIdversion0.12.3/version/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-impl/artifactIdversion0.12.3/versionscoperuntime/scope/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-jackson/artifactIdversion0.12.3/versionscoperuntime/scope/dependencyJWT 工具类ComponentpublicclassJwtUtil{Value(${jwt.secret:MySecretKeyForJWT2024})privateStringsecret;Value(${jwt.access-token-expiration:1800})// 30 分钟privatelongaccessTokenExpiration;Value(${jwt.refresh-token-expiration:604800})// 7 天privatelongrefreshTokenExpiration;privateSecretKeygetSignKey(){returnKeys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));}// 生成 Access TokenpublicStringgenerateAccessToken(LonguserId,Stringrole){returnJwts.builder().subject(String.valueOf(userId)).claim(role,role).claim(type,access).issuedAt(newDate()).expiration(newDate(System.currentTimeMillis()accessTokenExpiration*1000)).signWith(getSignKey()).compact();}// 生成 Refresh TokenpublicStringgenerateRefreshToken(LonguserId){returnJwts.builder().subject(String.valueOf(userId)).claim(type,refresh).issuedAt(newDate()).expiration(newDate(System.currentTimeMillis()refreshTokenExpiration*1000)).signWith(getSignKey()).compact();}// 解析 TokenpublicClaimsparseToken(Stringtoken){returnJwts.parser().verifyWith(getSignKey()).build().parseSignedClaims(token).getPayload();}// 校验 Token 是否有效publicbooleanvalidateToken(Stringtoken){try{parseToken(token);returntrue;}catch(JwtException|IllegalArgumentExceptione){returnfalse;}}// 从 Token 中获取用户 IDpublicLonggetUserId(Stringtoken){returnLong.parseLong(parseToken(token).getSubject());}}四、统一鉴权架构用户 网关 微服务 ┌────────┐ ┌─────────────────────────┐ ┌──────────┐ │ 登录请求 │───→│ ① 校验用户名密码 │ │ │ │ │ │ ② 签发 JWT │ │ user- │ │ │←───│ ③ 返回 Token │ │ service │ └────────┘ └─────────────────────────┘ └──────────┘ │ ┌────────┐ ┌─────▼───────────────────┐ ┌──────────┐ │ 业务请求 │───→│ ④ 全局过滤器校验 JWT │ │ order- │ │(带Token)│ │ ⑤ 解析用户信息 │──→│ service │ │ │ │ ⑥ 透传用户信息到 Header │ │ │ └────────┘ └─────────────────────────┘ └──────────┘4.1 网关全局过滤器Spring Cloud Gateway 中实现全局 JWT 校验ComponentSlf4jpublicclassJwtAuthFilterimplementsGlobalFilter,Ordered{AutowiredprivateJwtUtiljwtUtil;// 不需要校验的路径白名单privatestaticfinalListStringWHITE_LISTArrays.asList(/api/user/login,/api/user/register,/api/public/);OverridepublicMonoVoidfilter(ServerWebExchangeexchange,GatewayFilterChainchain){Stringpathexchange.getRequest().getURI().getPath();// 白名单直接放行if(isWhitePath(path)){returnchain.filter(exchange);}// 从请求头获取 TokenStringtokenexchange.getRequest().getHeaders().getFirst(Authorization);if(tokennull||!token.startsWith(Bearer )){returnunauthorized(exchange,未携带Token);}tokentoken.substring(7);// 去掉 Bearer 前缀// 校验 Tokenif(!jwtUtil.validateToken(token)){returnunauthorized(exchange,Token无效或已过期);}// 解析用户信息LonguserIdjwtUtil.getUserId(token);ClaimsclaimsjwtUtil.parseToken(token);Stringroleclaims.get(role,String.class);// 将用户信息写入请求头透传给下游微服务ServerHttpRequestrequestexchange.getRequest().mutate().header(X-User-Id,userId.toString()).header(X-User-Role,role).build();log.debug(用户 {} 请求 {},userId,path);returnchain.filter(exchange.mutate().request(request).build());}privatebooleanisWhitePath(Stringpath){returnWHITE_LIST.stream().anyMatch(path::startsWith);}privateMonoVoidunauthorized(ServerWebExchangeexchange,Stringmessage){ServerHttpResponseresponseexchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);Stringbody{\code\:401,\message\:\message\};DataBufferbufferresponse.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));returnresponse.writeWith(Mono.just(buffer));}OverridepublicintgetOrder(){return-100;// 高优先级在其他过滤器之前执行}}关键点用户信息通过自定义请求头透传。网关校验通过后把 userId 和 role 塞到X-User-Id和X-User-Role头里下游服务直接从请求头取就行不需要再解析 JWT。4.2 微服务端获取用户信息既然网关已经帮你解析好了下游服务直接取RestControllerRequestMapping(/api/order)publicclassOrderController{GetMapping(/my-orders)publicListOrdergetMyOrders(RequestHeader(X-User-Id)LonguserId){returnorderService.listByUserId(userId);}}更优雅的做法——自定义注解 参数解析器// 自定义注解Target(ElementType.PARAMETER)Retention(RetentionPolicy.RUNTIME)publicinterfaceCurrentUser{}// 参数解析器自动从请求头注入用户信息ComponentpublicclassCurrentUserResolverimplementsHandlerMethodArgumentResolver{OverridepublicbooleansupportsParameter(MethodParameterparameter){returnparameter.hasParameterAnnotation(CurrentUser.class);}OverridepublicObjectresolveArgument(MethodParameterparameter,ModelAndViewContainermavContainer,NativeWebRequestwebRequest,WebDataBinderFactorybinderFactory){HttpServletRequestrequestwebRequest.getNativeRequest(HttpServletRequest.class);LonguserIdLong.parseLong(request.getHeader(X-User-Id));Stringrolerequest.getHeader(X-User-Role);UserContextcontextnewUserContext();context.setUserId(userId);context.setRole(role);returncontext;}}// 使用GetMapping(/my-orders)publicListOrdergetMyOrders(CurrentUserUserContextuser){returnorderService.listByUserId(user.getUserId());}五、Token 刷新机制Access Token 设太长不安全泄露后风险期长太短用户体验差频繁登录。业界标准做法双 Token 机制。Access Token 过期 Refresh Token 过期 (30分钟) (7天) │ │ ────▼──────────────▶ 时间线 ──────────────────▼──── │ │ │ 正常使用 用 Refresh Token 需要重新登录 换取新 Access Token刷新接口实现PostMapping(/api/user/refresh)publicResultMapString,Stringrefresh(RequestParamStringrefreshToken){// 校验 Refresh Tokenif(!jwtUtil.validateToken(refreshToken)){thrownewBizException(Refresh Token 无效或已过期请重新登录);}ClaimsclaimsjwtUtil.parseToken(refreshToken);if(!refresh.equals(claims.get(type,String.class))){thrownewBizException(Token 类型错误);}// 检查 Refresh Token 是否在黑名单中已注销if(tokenBlacklistService.isBlacklisted(refreshToken)){thrownewBizException(Token 已注销请重新登录);}LonguserIdLong.parseLong(claims.getSubject());// 签发新的一对 TokenStringnewAccessTokenjwtUtil.generateAccessToken(userId,claims.get(role,String.class));StringnewRefreshTokenjwtUtil.generateRefreshToken(userId);// 旧的 Refresh Token 加入黑名单防止被恶意重复使用tokenBlacklistService.addToBlacklist(refreshToken,jwtUtil.getExpiration(refreshToken));MapString,StringtokensnewHashMap();tokens.put(accessToken,newAccessToken);tokens.put(refreshToken,newRefreshToken);returnResult.success(tokens);}六、Token 黑名单处理注销JWT 的最大软肋——无法主动失效。Token 发出去后在有效期内就是一张有效的通行证。解决方案用 Redis 维护一个黑名单登录时存进去网关校验时检查ServicepublicclassTokenBlacklistService{AutowiredprivateStringRedisTemplateredisTemplate;privatestaticfinalStringBLACKLIST_PREFIXjwt:blacklist:;// 加入黑名单TTL 设为 Token 剩余有效期publicvoidaddToBlacklist(Stringtoken,Dateexpiration){longttlexpiration.getTime()-System.currentTimeMillis();if(ttl0){redisTemplate.opsForValue().set(BLACKLIST_PREFIXtoken,1,ttl,TimeUnit.MILLISECONDS);}}publicbooleanisBlacklisted(Stringtoken){returnBoolean.TRUE.equals(redisTemplate.hasKey(BLACKLIST_PREFIXtoken));}}这样用户注销时把当前 Token 扔进黑名单网关校验时发现黑名单命中就直接拒绝。七、安全最佳实践Payload 不存敏感信息Payload 只是 Base64 编码不是加密。密码、手机号、身份证一律不往 Token 里塞密钥强弱决定安全高低HS256 场景下密钥至少 32 位随机字符。生产环境用 RS256非对称加密更安全全链路 HTTPSToken 在 HTTP 头里明码传输不用 HTTPS 等于裸奔Access Token 短时效15~30 分钟为宜。配合 Refresh Token 保证用户体验前端存储Web 端放 HttpOnly Cookie防 XSS移动端放 Keychain/Keystore。不要放 localStorage总结JWT 网关全局鉴权是微服务认证的黄金搭档——网关作为统一入口校验 Token、解析用户身份、透传给下游每个微服务无需重复写鉴权逻辑。配合双 Token 刷新和 Redis 黑名单安全性和用户体验兼得。

相关新闻

ActiChat v1.1.0 Skill系统实战:从零构建可扩展的智能对话机器人

ActiChat v1.1.0 Skill系统实战:从零构建可扩展的智能对话机器人

大家好,我是专注于技术实战分享的博主。在日常开发中,我们常常会遇到需要为聊天机器人或智能助手扩展功能的需求,比如让它能联网搜索信息或查询精准时间。手动集成这些能力不仅繁琐,而且难以维护和扩展。今天,我们就来…

2026/8/1 2:20:39 阅读更多 →
RocketMQ消息队列:业务异步解耦、设备消息分发

RocketMQ消息队列:业务异步解耦、设备消息分发

RocketMQ消息队列:业务异步解耦、设备消息分发订单创建后要发邮件、发短信、扣库存、记日志——如果全串行执行,用户等得花都谢了。消息队列就是来解这种"一个操作触发一堆事情"的耦的。今天主角是阿里系扛把子 RocketMQ。一、消息队列三兄弟&…

2026/8/1 2:20:39 阅读更多 →
基于Web Audio API的步进音序器开发指南:从原理到实践

基于Web Audio API的步进音序器开发指南:从原理到实践

这次我们来看一个个人开发者在家自制的音乐编曲应用。这个项目的核心不是又一个复杂的数字音频工作站(DAW),而是一个聚焦于“步进音序器”这一经典编曲方式的轻量化工具。它解决了传统DAW入门门槛高、操作复杂的问题,让音乐创作的…

2026/8/1 2:20:39 阅读更多 →

最新新闻

嵌入式存储开发指南:从NAND Flash时序图到可靠驱动设计

嵌入式存储开发指南:从NAND Flash时序图到可靠驱动设计

1. 从一张“天书”到一份“说明书”如果你刚接触嵌入式存储,或者第一次拿到Nand Flash的数据手册,翻到时序图那一页,大概率会和我当初一样,感觉眼前一黑。那些纵横交错的信号线,一堆缩写(tWC, tWP, tREH...…

2026/8/1 3:08:56 阅读更多 →
千笔AI:专科生论文写作全流程智能解决方案

千笔AI:专科生论文写作全流程智能解决方案

1. 千笔AI:专科生论文写作的智能助手作为一名经历过专科论文写作煎熬的老学长,我深知专科生在学术写作中面临的困境:文献检索能力弱、格式规范不熟悉、语言表达不专业。最近实测了一款名为"千笔AI"的论文辅助工具,它针对…

2026/8/1 3:08:56 阅读更多 →
STM32H743入门实战:从环境搭建到LED与按键控制

STM32H743入门实战:从环境搭建到LED与按键控制

1. 项目概述:从零上手一块高性能MCU拿到一块全新的STM32H743开发板,看着密密麻麻的引脚和复杂的芯片型号,很多朋友的第一反应可能是兴奋,紧接着就是一丝迷茫:功能这么强大,我该从哪里开始?我的经…

2026/8/1 3:08:56 阅读更多 →
Android逆向实战:非ROOT环境下Frida重打包注入完整指南

Android逆向实战:非ROOT环境下Frida重打包注入完整指南

1. 项目概述:为什么我们需要在非ROOT环境下折腾Frida?如果你接触过移动安全或者逆向工程,Frida这个名字对你来说一定不陌生。它就像一把瑞士军刀,能让你在运行时动态地注入JavaScript代码,去Hook函数、修改逻辑、分析数…

2026/8/1 3:08:56 阅读更多 →
深入理解C语言static关键字的本质与应用

深入理解C语言static关键字的本质与应用

1. static关键字的本质理解在C语言中,static可能是最容易被初学者误解的关键字之一。我第一次接触这个概念时,曾天真地认为它只是"静态"的意思,直到在项目调试中遇到一个诡异的变量值保持问题,才真正理解它的威力。stat…

2026/8/1 3:08:56 阅读更多 →
从零构建完整项目开发流程的技术实践

从零构建完整项目开发流程的技术实践

1. 项目概述作为一名从业多年的技术博主,我经常遇到这样的情况:一个看似简单的项目标题背后,往往隐藏着丰富的技术内涵和实践价值。今天我们就来聊聊如何从零开始构建一个完整的项目开发流程,分享我在实际工作中的经验总结。这个项…

2026/8/1 3:07:55 阅读更多 →

日新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →