api-server/docs/ios-auth-api-contract.md
wangdl b9e6055400
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 41s
fix: H0-01 彻底阻断生产环境 mock + 结构化错误码 + iOS Auth 合同文档
- apple-auth.service.ts: verifyIdentityToken 增加 NODE_ENV 检查,
  生产环境缺 APPLE_BUNDLE_ID 时运行时返回 401,不再走 mock
- 新增 CAPIErrorCode 语义错误码体系 (src/common/errors/)
- 新增 CapiException 携带 errorCode 的 HttpException 子类
- GlobalExceptionFilter 响应自动包含 errorCode 字段
- AuthService/JwtAuthGuard/AppleAuthService 全部改用 CapiException
- 新增 LoginResponseDto/RefreshResponseDto/LogoutResponseDto/UserDto
- Auth controller Swagger 添加 type 参数
- 新增 docs/ios-auth-api-contract.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 21:03:15 +08:00

5.0 KiB
Raw Permalink Blame History

iOS Auth API Contract

冻结日期2026-05-27 | 版本1.0 | 未经评审不得修改请求/响应字段

1. 基础约定

项目
Base URL生产 https://api.longde.cloud
Content-Type application/json
认证方式 Authorization: Bearer <accessToken>
成功响应格式 { success: true, data: <T>, timestamp: "ISO8601" }
错误响应格式 { success: false, statusCode: <int>, message: "<中文>", errorCode: "<语义码>" }

2. Token 生命周期

Token 有效期 存储位置
accessToken (JWT) 1 小时 Keychain
refreshToken (opaque) 7 天 Keychain
  • refreshToken 是一次性的:每次 /auth/refresh 成功后旧的立即吊销,返回新的
  • accessToken 过期 → iOS 用 refreshToken 换新,不要重新走 Apple 登录
  • refreshToken 过期 → 回到登录页

3. 接口清单

3.1 Apple 登录

POST /auth/apple

请求体:

字段 类型 必需 说明
identityToken string Apple 返回的 JWT identityToken
authorizationCode string Apple 返回的授权码(建议传)
nonce string iOS 生成的原始 nonce未哈希
fullName.givenName string 用户的名
fullName.familyName string 用户的姓
email string Apple 返回的邮箱

成功响应 data

字段 类型 说明
accessToken string JWT含 type: "user"
refreshToken string 96 位十六进制字符串
user.id string 用户 ID
user.email string|null 邮箱
user.nickname string|null 昵称
user.avatarUrl string|null 头像 URL
user.role string 角色
user.status string 状态
user.onboardingCompleted boolean 是否完成引导

错误:

errorCode HTTP 说明
AUTH_INVALID_APPLE_TOKEN 401 identityToken 无效、过期或验证失败

3.2 刷新 Token

POST /auth/refresh

请求体:

字段 类型 必需
refreshToken string

成功响应 data 同登录响应(新 accessToken + 新 refreshToken + user

错误:

errorCode HTTP 说明
AUTH_REFRESH_TOKEN_EXPIRED 401 超过 7 天未使用
AUTH_REFRESH_TOKEN_REVOKED 401 已被登出/安全事件撤销
AUTH_USER_DISABLED 401 账号被管理员禁用
AUTH_USER_DELETED 401 账号已注销

3.3 获取当前用户

GET /users/me

需要 Bearer token。

成功响应 data 用户对象(同登录响应中的 user

错误:

errorCode HTTP 说明
AUTH_UNAUTHORIZED 401 未登录或 token 过期
AUTH_USER_DISABLED 401 账号被禁用
AUTH_USER_DELETED 401 账号已注销
AUTH_WRONG_TOKEN_TYPE 401 使用了 admin token

3.4 登出

POST /auth/logout

需要 Bearer token。

请求体:

字段 类型 必需
refreshToken string

成功响应: { success: true, message: "已退出登录" }

错误:

errorCode HTTP 说明
AUTH_UNAUTHORIZED 401 token 已过期(不影响客户端清本地状态)

4. 完整错误码表

errorCode 含义 iOS 处理策略
AUTH_INVALID_APPLE_TOKEN Apple token 验证失败 提示用户重试 Apple 登录
AUTH_USER_DISABLED 账号被禁用 清空本地 session显示禁用提示
AUTH_USER_DELETED 账号已注销 清空本地 session回到欢迎页
AUTH_REFRESH_TOKEN_EXPIRED Refresh token 过期 清空本地 session回到登录页
AUTH_REFRESH_TOKEN_REVOKED Refresh token 被撤销 清空本地 session回到登录页
AUTH_UNAUTHORIZED 未认证 尝试 refresh失败则回登录页
AUTH_WRONG_TOKEN_TYPE Token 类型错误 清空本地 session重新登录
AUTH_DEV_LOGIN_FORBIDDEN 生产环境禁用 dev 登录 不触发(仅 iOS 不关心)
VALIDATION_ERROR 请求参数校验失败 检查发送的字段
NOT_FOUND 资源未找到 提示用户
FORBIDDEN 权限不足 提示用户
RATE_LIMITED 请求过快 稍后重试
INTERNAL_ERROR 服务器错误 提示用户稍后重试

5. iOS 实现要点

  1. Token 存储 — 用 Keychain不是 UserDefaults
  2. 401 自动刷新 — APIClient 拦截 401用 refreshToken 换新 accessToken失败则清 session
  3. 并发刷新 — 多个请求同时 401 时只发一次 refresh
  4. AppSession 状态 — 维护状态机:unauthenticated → authenticating → authenticated → refreshing/expired/disabled/deleted
  5. Apple 登录 nonce — 用 SecRandomCopyBytes 生成SHA256 后传给 Apple原始值传给后端
  6. authorizationCode — 提取并传给后端