拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Auth架构设计

Auth架构设计

Auth 架构设计

多应用、多终端的认证鉴权,核心不是给每个系统都写一套登录逻辑,而是把身份可信链路收口成三件事:身份中心负责认证,网关负责鉴权,JWT 作为无状态凭证在系统间传递。本文把这三件事放到统一账号系统、Spring Cloud Gateway、Spring Security 和 Redis 的架构里讲清楚。

一、先分清三个词

很多人把 JWT、认证、鉴权混在一起,但它们处在不同层面:

概念回答的问题落地位置一句话解释
Authentication 认证你是谁认证中心 / 登录流程验证用户身份是否合法
Authorization 鉴权你能做什么网关 / 资源服务判断用户是否有权访问某个应用或接口
JWT用什么证明身份请求头Authorization: Bearer一种无状态、可验签的身份凭证格式

可以这样比喻:

  • 认证是小区保安确认“你是不是业主”;
  • 鉴权是保安继续确认“你只能进自己单元,不能进付费健身房”;
  • JWT是那张带签名、带身份信息和有效期的电子业主卡。

还有一个容易混淆的关系:JWT 是 Token 格式,OAuth2 是授权框架。实际项目中通常是 OAuth2 完成授权流程,授权成功后返回一个 JWT 格式的access_token。

二、先定义架构要解决什么

在 Mall 这类多应用电商系统里,认证鉴权要同时解决四类问题:

痛点典型表现
登录状态不共享App 登录后,进入官网还要重新输密码
权限边界混乱商品运营能删订单,区域店员能看全国报表
重复造轮子每个微服务都写一遍登录、验 Token、查权限
性能与安全难以兼顾查库鉴权打满数据库,JWT 又存在主动登出难题

所以合理的架构目标不是“功能能跑”,而是:

  1. 用户一次登录,多个应用、多个终端都能识别身份;
  2. 不同应用、不同角色访问不同权限,权限变更能秒级生效;
  3. 业务服务不重复实现认证鉴权,只专注业务;
  4. 高并发下鉴权链路不能被数据库拖垮。

三、统一认证:授权码模式的 SSO 链路

统一账号系统通常称为 UAA(Unified Authentication Authority)。多应用场景推荐使用 OAuth2.0 授权码模式,而不是让前端直接拿密码换 Token。

核心原因是授权码模式把敏感信息留在后端:浏览器只能拿到一次性的code,真正的access_token必须由业务后端带着client_secret换取。

业务微服务Gateway统一认证中心业务后端用户浏览器业务微服务Gateway统一认证中心业务后端用户浏览器访问 /oauth/authorize?client_id=...&redirect_uri=...1完成用户名密码 / MFA 认证2302 返回一次性 authorization_code3携带 code 回调业务后端4用 code + client_secret 换取 access_token5返回 JWT access_token + refresh_token6保存登录态,后续请求带 Token7Authorization: Bearer access_token8验签、过期、黑名单、权限校验9放行并透传用户上下文10

这个流程里有三类凭证,作用完全不同:

凭证生命周期存储位置核心作用
authorization_code5-10 分钟,一次性重定向 URL 中短暂出现把“用户已授权”安全传给业务后端
access_token通常 1-2 小时前端 Cookie / Storage,请求头传递访问业务资源的真正通行证
refresh_token数天到数周后端 HttpOnly Cookie / DB在 access_token 过期后静默续期

设计要点:

  • authorization_code必须配合client_secret才能换 Token,浏览器截获也无法直接使用;
  • refresh_token不暴露给前端 JavaScript,否则长期凭证就失去了保护;
  • JWT 只放userId、username、roleType、exp等非敏感字段,不放手机号、邮箱、密码和完整权限列表。

四、统一鉴权:认证之后还要划清权限边界

认证通过只代表“这是个合法用户”,不代表“他有权访问这个系统”。多应用场景下,鉴权需要两个维度同时成立:

当前用户 + 当前系统 + 当前终端 -> 是否拥有当前 URL 权限

4.1 网关里的三层 Filter

统一鉴权通常收口到 Spring Cloud Gateway。一个请求进入网关后,可以按三层责任链处理:

层级动作实现
第一层:身份认证校验 JWT 是否合法、是否过期、是否在黑名单JwtUtil.verify(token)
第二层:权限加载根据用户、系统、终端读取权限集合redis.get("user:perms:" + userId + ":" + systemCode)
第三层:访问控制匹配当前 URL 和请求方法是否在权限集合中AntPathMatcher+system_code

合法

通过

401

403

业务请求

Gateway

第一层:JWT 验签

第二层:Redis 加载权限

第三层:URL + Method 匹配

业务微服务

拒绝

拒绝

4.2 用 system_code 做系统间隔离

只做 RBAC 不够。同一个用户在不同系统里,权限可能完全不同。所以在权限模型中增加system_code字段:

user_id + role_id + permission_code | +-- system_code 例如 product / order / inventory / admin +-- terminal_type 例如 pc / app / miniprogram

这样就能表达:

  • 华东区店员只能查看本店销售数据;
  • 总部运营可以查看全国经营报表;
  • 抢购活动配置只允许特定运营角色操作;
  • 同一用户在 App 能看完整订单,在小程序只能看简化订单。

4.3 权限动态刷新

权限不能每次请求都查数据库。正确做法是登录后写入 Redis,权限变更时通过消息队列广播刷新:

权限管理后台

RabbitMQ / RocketMQ

权限刷新监听器

更新 Redis 权限缓存

网关下次请求读新权限

收益很直观:鉴权从查库的 80ms 级别降到查 Redis 的 8ms 级别,权限变更从“重启服务”变成秒级生效。

五、为什么 JWT 比直接传用户名密码更安全

JWT 的安全不是“加密了所以安全”,而来自它带来的三个变化:

5.1 不再重复传输密码

传统方式下,用户每次访问都可能携带账号密码或服务端 Session ID。JWT 只在登录时交换一次用户名密码,后续请求使用经过签名的 Token,密码不会反复暴露。

5.2 签名保证不可篡改

JWT 由Header.Payload.Signature三部分组成。签名端使用后端私密密钥计算,任何对 payload 的修改都会导致验签失败。即使攻击者拿到 Token,也无法把普通用户改成管理员。

5.3 生命周期可控

项目里可以设置access_token2 小时、refresh_token7 天。即使 Token 泄露,攻击窗口也被限制在有限时间内。

但 JWT 并不是完美方案,生产环境必须补上三块:

  1. Token 黑名单:JWT 天然无法主动失效,登出时把jti + 剩余有效期写入 Redis,网关先查黑名单再验签;
  2. HTTPS + HttpOnly:Token 传输必须加密,浏览器端优先 HttpOnly Cookie,降低 XSS 窃取风险;
  3. 轻量 payload:完整权限不放 Token,只在 Token 中放最小身份标识,避免 Token 过大和敏感信息暴露。

六、推荐落地架构

综合上面的问题,推荐采用:

Spring Cloud Gateway + Spring Security + JWT + Redis + MQ
组件职责
UAA 认证中心统一登录、OAuth2 授权码签发、Token 签发与刷新
Spring Cloud Gateway总入口,统一验签、加载权限、做访问控制
JWT无状态身份凭证,支持多应用和多终端传递
Redis缓存权限、Token 黑名单、短时授权码
MQ广播权限变更,触发 Redis 刷新
Nacos管理 client 白名单、密钥、路由配置

整体可以拆成两条主链路。

链路一:登录与 Token 签发

1. 登录 / OAuth 授权

2. 校验身份并签发 JWT

3. 写入权限缓存 / 黑名单

PC / App / 小程序

UAA 认证中心

Redis

链路二:业务请求与网关鉴权

1. Authorization: Bearer JWT

通过

读取

返回权限

PC / App / 小程序

Spring Cloud Gateway

2. JWT 验签 / 过期 / 黑名单

3. Redis 加载 RBAC 权限

4. URL + Method 匹配

商品 / 订单 / 库存 / 会员 / 运营后台

Redis

权限刷新属于旁路,不参与每次业务请求:

1. 修改角色 / 权限

2. 广播变更事件

3. 更新 Redis

4. 网关下次请求读取

权限管理后台

MQ

权限刷新监听器

Redis

Spring Cloud Gateway

对于单体项目,可以不引入网关,直接用 Spring Security + JWT + RBAC 完成认证与动态鉴权。对于响应式微服务项目,则把 Spring Security 的阻塞 API 换成 WebFlux 版本,使用ReactiveAuthenticationManager、ReactiveUserDetailsService和响应式 Redis 客户端,避免高并发下同步过滤器成为瓶颈。

七、设计原则

最后收敛成五条可以复用的原则:

  1. 认证与鉴权分离:Token 只证明身份,权限由网关或服务端动态加载;
  2. 缓存前置:高频权限优先走本地缓存,其次 Redis,最后数据库;
  3. 系统维度隔离:多系统共用一套账号时,必须用system_code和terminal_type划清边界;
  4. 最小暴露:JWT payload 只放最小身份信息,不放 PII,不放完整权限;
  5. 可撤销可追溯:黑名单解决 JWT 无法主动登出的问题,鉴权失败记录日志,配合审计满足合规要求。

小结

Auth 架构设计的核心,不是把 JWT、Gateway、Redis 这些组件堆在一起,而是先分清“认证、鉴权、凭证”三件事,再把它们放到一条清晰的请求链路上:认证中心发证,网关验证并授权,业务服务只处理业务。这套思路可以从单体项目扩展到多应用、多终端的微服务体系。

返回列表