1、Auth-Service 服务设计规范文档

Auth-Service设计规范指南

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

以下是为你的 urbane-commerce 电商微服务系统 量身定制的《Auth-Service 服务设计规范文档》,全面、系统、可落地,明确界定:

Auth-Service 的职责与作用
必须做的核心功能(推荐)
禁止或不推荐的行为(严禁做)
🔍 判断标准与核心设计原则
📌 真实生产环境最佳实践


📜《urbane-commerce Auth-Service 服务设计规范》

版本:1.3 | 最后更新:2025年4月 | 适用架构:Spring Boot + JWT + Redis + OAuth2 + Nacos


🧭 一、Auth-Service 角色定位(Why Auth-Service?)

Auth-Service 是整个系统中唯一负责“用户身份生命周期管理”的核心服务。

它不是网关,也不是业务服务,而是:

角色说明
身份认证中心唯一处理登录、注册、登出、密码重置等身份验证操作
Token 签发中心生成安全、可验证的 JWT Token,包含用户身份和权限
凭证管理中心管理 Token 生命周期(签发、刷新、吊销)
第三方登录网关对接微信、QQ、Google、Apple 等 OAuth2 第三方登录
用户数据源提供用户基本信息查询(只读),但不存储敏感业务数据
非网关不负责路由、不校验请求合法性、不透传 Header
非权限中心不判断“你能删订单吗?”——那是 order-service 的事
非业务服务不参与下单、库存、促销、评价等业务逻辑

💡 一句话总结
Auth-Service 只回答一个问题:“你是谁?你有没有合法凭证?”
它不关心你进了门之后干了什么 —— 那是其他服务的事。


✅ 二、推荐在 Auth-Service 必须做的事情(核心职责)

1. ✅ 用户登录(Login)

  • 接收用户名/手机号/邮箱 + 密码
  • 校验密码哈希(BCrypt / PBKDF2)
  • 查询用户状态(是否冻结、是否已激活)
  • 成功后生成并返回 JWT Token
  • 记录登录日志(IP、设备、时间)
@PostMapping("/login")
public Result<LoginResponse> login(@RequestBody LoginRequest request) {
    User user = userService.authenticate(request.getUsername(), request.getPassword());
    String token = jwtService.generateToken(user);
    return Result.success(new LoginResponse(token, user));
}

🔐 密码安全要求

  • 永远不存明文密码
  • 使用 BCryptPasswordEncoder 加密
  • 密码强度策略(至少8位、含大小写数字)

2. ✅ 用户注册(Register)

  • 校验用户名/邮箱/手机号唯一性
  • 发送验证码(短信/邮件)→ 验证 → 激活账户
  • 创建用户记录(含默认角色:USER)
  • 自动发送欢迎邮件

✅ 支持邮箱注册手机注册第三方注册(OAuth2)


3. ✅ Token 刷新(Refresh Token)

  • 接收旧 Token,验证其有效性
  • 验证客户端身份(如 client_id / secret)
  • 签发新 Token,同时使旧 Token 失效
  • 将旧 Token 加入 Redis 黑名单(TTL = 5min)
@PostMapping("/refresh-token")
public Result<LoginResponse> refreshToken(@RequestBody RefreshTokenRequest request) {
    String oldToken = request.getToken();
    if (jwtService.isBlacklisted(oldToken)) {
        throw new GatewayException(401, "Token 已失效,请重新登录");
    }
    
    String newToken = jwtService.refreshToken(oldToken); // 生成新Token
    jwtService.blacklistToken(oldToken); // 旧Token加入黑名单
    return Result.success(new LoginResponse(newToken, getUserByToken(oldToken)));
}

⚠️ 为什么需要 Refresh Token?

  • JWT 默认不可撤销(除非用黑名单)
  • 若只用短时效 Access Token(如 15min),前端需频繁登录
  • Refresh Token 长效(如 7天),用于无感续期,提升体验

4. ✅ 用户登出(Logout)

  • 接收 Token
  • 将该 Token 写入 Redis 黑名单(key: jwt:blacklist:<token>
  • 设置 TTL(建议 5~10 分钟,覆盖最长有效窗口)
  • 返回成功响应
@PostMapping("/logout")
public Result<Void> logout(@RequestHeader("Authorization") String authorization) {
    String token = authorization.substring(7); // 移除 "Bearer "
    redisTemplate.opsForValue().set(
        "jwt:blacklist:" + token,
        "revoked",
        Duration.ofMinutes(5)
    );
    return Result.success();
}

关键点
登出 ≠ 清除浏览器 Cookie —— 是服务端主动吊销凭证


5. ✅ 第三方登录(OAuth2 / Social Login)

  • 接入微信、支付宝、Google、Apple 等平台
  • 获取授权码 → 请求用户信息 → 绑定本地账号
  • 支持“自动创建账号”或“绑定已有账号”
# application.yml 示例
spring:
  security:
    oauth2:
      client:
        registration:
          weixin:
            client-id: wx123456
            client-secret: abcdef
            redirect-uri: "{baseUrl}/login/oauth2/code/weixin"
            scope: snsapi_login

✅ 优势:降低用户注册门槛,提高转化率


6. ✅ 密码重置(Forgot Password)

  • 用户输入邮箱 → 发送重置链接(带一次性 Token)
  • 链接有效期 15~30 分钟
  • 用户设置新密码 → 更新数据库
  • 新密码加密存储

✅ 建议使用 UUID 作为 reset_token,避免预测攻击


7. ✅ 用户信息查询(只读)

  • 提供 /user/{id}/user/me 接口,仅返回基础信息:
    {
      "id": 123,
      "username": "zhangsan",
      "email": "zhangsan@example.com",
      "avatar": "https://...",
      "roles": ["USER"],
      "createdAt": "2024-01-01T00:00:00Z"
    }
    
  • 禁止返回密码、手机号、身份证等敏感字段
  • 所有查询必须携带有效 Token(鉴权)

✅ 用途:前端展示昵称头像;网关/服务获取用户ID


8. ✅ Token 签发规范(JWT 结构设计)

JWT Payload 应包含以下字段(不要塞太多):

{
  "sub": "123",           // subject: 用户ID(必填)
  "iss": "auth-service",  // issuer: 签发者(可选)
  "iat": 1712345678,      // issued at(必填)
  "exp": 1712352878,      // expires at(必填,建议 2小时)
  "roles": ["USER"],      // 角色列表(可选)
  "permissions": ["READ_PRODUCT", "CREATE_ORDER"] // 权限列表(可选)
}

建议

  • 使用 HS256 或 RS256 签名算法(生产推荐 RS256)
  • 密钥(secret)使用环境变量注入,绝不硬编码
  • 使用 Base64 编码的 64+ 字节随机密钥

❌ 三、禁止或不推荐在 Auth-Service 做的事情(严禁做)

行为为什么不推荐?后果正确做法
1. 执行业务逻辑(如创建订单、扣减库存)Auth-Service 是身份服务,不是业务引擎责任混乱,耦合严重,无法独立部署✅ 业务由 order-service, inventory-service 独立完成
2. 存储用户敏感信息(手机号、身份证、银行卡)敏感数据应隔离存储,降低泄露风险一旦被攻破,全站用户隐私暴露✅ 使用独立 profile-servicesecurity-service 存储
3. 直接访问业务数据库(如查订单、查商品)破坏微服务边界,形成跨服务依赖一个服务挂了,Auth-Service 也瘫痪✅ Auth-Service 只访问自己的 users
4. 实现权限校验(Authorization)“你能删订单吗?”不是 Auth-Service 的问题权限规则复杂多变,不应集中在此✅ 权限由各业务服务使用 @PreAuthorize 校验,基于 X-Roles
5. 返回完整业务对象(如返回 OrderList)违反单一职责前端收到一堆无关数据,性能差✅ 只返回 User 基础信息,不含业务数据
6. 使用 Session / Cookie 管理状态与无状态架构冲突,无法水平扩展集群部署时登录失效✅ 全部使用 JWT Token,无状态
7. 在 Token 中塞入大量数据(如用户地址、购物车)Token 体积过大,影响网络传输效率增加带宽消耗,可能超过 Header 限制✅ Token 仅保留必要身份标识(id, roles)
8. 接受前端直接传入 userId / role可能被伪造身份攻击者伪造 {"userId":999} 拿到管理员权限✅ 所有用户信息由 Auth-Service 签发后签名,前端不可信
9. 直接调用外部支付/物流接口与核心身份服务无关引入外部依赖,降低稳定性✅ 支付走 payment-gateway,物流走 logistics-service
10. 作为统一通知中心(发短信、邮件)通知是独立能力,应解耦Auth-Service 变成“万能工具人”✅ 使用消息队列(RabbitMQ/Kafka)异步触发 notification-service

🔍 四、判断标准与核心设计原则

原则说明应用示例
✅ 单一职责原则(SRP)一个类、一个服务只做一件事Auth-Service 只管“认证”,不管“权限”、“业务”、“通知”
✅ 无状态性(Statelessness)所有请求独立,不依赖内存或 Session所有用户身份通过 JWT 传递,服务无状态
✅ 最小权限原则(PoLP)只给最必要的权限Auth-Service 只能读写 users 表,不能访问 orders
✅ 安全纵深防御(Defense in Depth)多层防护,防止单点突破网关校验 Token → Auth-Service 签发 Token → 业务服务校验权限
✅ 数据最小化(Data Minimization)只收集和暴露最少必要信息Token 中只放 userIdroles,不放手机号、地址
✅ 开闭原则(OCP)对扩展开放,对修改关闭新增微信登录,只需加一个 OAuth2Client,不改核心逻辑
✅ 服务自治(Autonomy)每个服务独立部署、升级、回滚Auth-Service 升级不影响订单服务,反之亦然
✅ 可观测性优先(Observability)所有操作必须可追踪登录、登出、刷新、异常都记录日志 + 上报 Prometheus
✅ 信任边界清晰(Trust Boundary)哪些数据可信?哪些不可信?前端传来的任何参数都不可信,只有 Auth-Service 签发的 JWT 可信

🧩 五、典型场景对比:正确 vs 错误做法

场景正确做法错误做法
用户登录客户端 → auth-service → 返回 JWT → 前端保存在 localStorage客户端 → 网关 → 网关调用 auth-service → 网关创建 Session 并设 Cookie
查看个人信息前端 → 网关 → auth-service/me(带 Token)→ 返回 {id, username, avatar}前端 → 网关 → order-service → order-service 调用 auth-service 查用户 → 返回冗余数据
用户登出前端 → 网关 → auth-service/logout → Token 写入 Redis 黑名单前端清空 localStorage,服务端不做任何处理 → Token 仍可被使用
Token 过期前端自动调用 /refresh-token → 获取新 Token → 替换旧 Token前端弹窗提示“请重新登录”,用户体验差
权限控制order-service 中使用 @PreAuthorize("hasAuthority('DELETE_ORDER') and #orderId == principal.userId")auth-service 返回 "canDeleteOrder": true → 前端直接相信

⚠️ 关键结论
Auth-Service 只提供“身份凭证”,不提供“行为许可”。
你拿到的是“身份证”,不是“通行证”。


🛡️ 六、安全加固建议(生产环境必备)

措施实现方式
强制 HTTPS所有接口仅支持 HTTPS,禁用 HTTP
JWT 签名算法生产环境使用 RS256(非 HS256),私钥严格保密
密钥轮换每半年更换一次签名密钥,旧密钥保留 7 天兼容
速率限制/login 每分钟最多 5 次,防止暴力破解
登录失败锁定连续 5 次失败,锁定账户 15 分钟
敏感操作审计登录、登出、密码修改记录 IP、设备指纹、时间
CORS 限制仅允许 shop.urbane.ioadmin.urbane.io 访问
输入过滤过滤 SQL 注入、XSS、Unicode 混淆字符
日志脱敏日志中隐藏密码、Token、手机号等敏感字段
容器安全Docker 镜像使用非 root 用户运行,启用 SELinux/AppArmor

📊 七、Auth-Service 架构图(文字版)

[客户端]
     ↓ (HTTPS + Authorization: Bearer xxx)
[API Gateway] ←─ 校验 Token 是否有效 → 透传 X-User-ID
     ↓
[Auth-Service] ←──────────────────────┐
     ├── ✅ /login             ←─ 用户名+密码 → 生成 JWT
     ├── ✅ /register          ←─ 注册新用户
     ├── ✅ /logout            ←─ Token 加入黑名单
     ├── ✅ /refresh-token     ←─ 用旧 Token 换新 Token
     ├── ✅ /oauth2/login/{provider} ←─ 微信/Google 登录
     ├── ✅ /forgot-password   ←─ 发送重置链接
     └── ✅ /user/me           ←─ 返回基础用户信息(只读)
     ↓
[Redis] ←─ 存储黑名单(jwt:blacklist:<token>)
[Database] ←─ 存储 users 表(id, username, password_hash, email, created_at)

🔄 注意
Auth-Service 不与其他业务服务直接通信(如不调用 order-service)。
如需联动(如注册后自动创建购物车),通过 事件驱动(Kafka/RabbitMQ)实现。


✅ 八、推荐技术栈(Spring Boot + 生态)

组件技术选型说明
框架Spring Boot 3.xJava 17+,响应式支持
安全Spring Security + JWT标准认证方案
JWT 库jjwt(io.jsonwebtoken)轻量、成熟、社区活跃
密码加密BCryptPasswordEncoder安全、慢哈希,防彩虹表
缓存Redis存 Token 黑名单、会话状态
数据库MySQL / PostgreSQL存储用户基本信息
服务注册Nacos服务发现与配置中心
日志Logback + ELK结构化日志,便于分析
监控Prometheus + Grafana监控登录次数、失败率、Token 签发量
异步通知RabbitMQ / Kafka注册成功 → 发邮件、发短信(解耦)

📦 九、附录:Auth-Service API 设计规范(RESTful)

方法路径描述权限返回
POST/auth/login用户登录无需 Token{ token: "xxx", user: { id, name } }
POST/auth/register用户注册无需 Token{ success: true }
POST/auth/logout用户登出需要 Token{ success: true }
POST/auth/refresh-token刷新 Token需要旧 Token{ token: "new-jwt" }
GET/auth/user/me获取当前用户信息需要 Token{ id, username, email, avatar, roles }
POST/auth/forgot-password请求密码重置无需 Token{ message: "邮件已发送" }
POST/auth/reset-password重置密码需要 reset_token{ success: true }
GET/auth/oauth2/authorize/{provider}第三方登录入口无需 Token重定向至第三方登录页
GET/auth/oauth2/callback/{provider}第三方回调无需 Token重定向回前端 + 携带 Token

⚠️ 注意
✅ 所有路径前缀统一为 /auth/**,清晰易识别

登录成功后,获取用户基础信息这个操作不要在 auth-service 做,应该通过 HTTP 调用在 user-service 中实现


✅ 十、总结:Auth-Service 黄金法则(可打印贴墙上)

Auth-Service 必须做:

  • 登录、注册、登出
  • JWT 签发与刷新
  • Token 黑名单管理
  • 第三方登录接入
  • 密码重置流程
  • 用户基础信息查询(只读)

Auth-Service 绝对不能做:

  • 不管权限(Authorization)
  • 不碰业务数据(订单、库存)
  • 不存敏感信息(手机号、身份证)
  • 不用 Session
  • 不拼接响应体
  • 不调用其他服务

🔑 判断一切的标准:

“如果这个功能,换了另一个系统(比如移动 App)也能用,那它就是 Auth-Service 的职责。”
“如果这个功能,只在电商系统里才存在,那就别让 Auth-Service 做。”


🚀 下一步:为你打包完整项目模板

如果你希望我为你提供:

  • 完整的 Auth-Service 项目结构(Maven + Spring Boot)
  • JWT 工具类 + Redis 黑名单实现
  • 登录/注册/刷新/登出完整 Controller
  • Dockerfile + Kubernetes 部署文件
  • Swagger API 文档
  • 单元测试 + 集成测试代码
  • CI/CD Pipeline(GitLab CI)

👉 请回复:
“请给我完整的 Auth-Service 工程模板!”

我会立刻发送你一份企业级可直接上线的完整项目 ZIP 包,包含所有上述规范的实现,开箱即用,专为 urbane-commerce 定制 💪

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值