2026-05-15 17:29:57 +08:00

4.4 KiB
Raw Blame History

iOS 登录流程 —— 总体设计


一、核心理解

Apple 登录不是你的 App 登录系统本身。
Apple 只是帮你证明"这个人是谁"。
真正的登录态,要由你的后端发 accessToken / refreshToken。

最终流程:

iOS 调 Apple 登录
→ 拿到 Apple identityToken
→ 发给你的 NestJS 后端
→ 后端校验 Apple token
→ 后端创建 / 查找用户
→ 后端生成自己的 accessToken + refreshToken
→ iOS 存 Keychain
→ 以后所有接口带 Authorization: Bearer accessToken

开发建议:先做 dev-login → /users/me → Keychain → 知识库接口Apple 登录随后再接,不要让 Apple 流程卡住后端开发。


二、认证系统核心模型

后端登录系统的本质是建立自己的认证体系:

users
+ auth_accounts           (支持多 providerDEV、APPLE
+ refresh_tokens          (只存 hash不存明文
+ accessToken             短期令牌JWT
+ refreshToken            长期令牌JWT可轮换/撤销)
+ JwtAuthGuard            (全局守卫)
+ /users/me               (启动态判定核心接口)

Apple 登录只是其中一个 provider。核心是通过 auth_accounts 表关联第三方身份与本地用户。


三、接口清单

第一版 5 个接口:

接口 用途 优先级
POST /api/auth/dev-login 开发调试登录 先做
POST /api/auth/refresh 刷新登录态 先做
GET /api/users/me 获取当前用户 先做
POST /api/auth/apple Apple 正式登录 随后接
POST /api/auth/logout 退出登录 最后做

四、统一返回格式

登录成功后后端统一返回:

{
  "accessToken": "eyJ...",
  "refreshToken": "eyJ...",
  "user": {
    "id": "user_xxx",
    "email": "test@zhixi.app",
    "nickname": "测试用户",
    "avatarUrl": null,
    "role": "USER",
    "status": "ACTIVE",
    "onboardingCompleted": false
  }
}

iOS 拿到后:

数据 存储位置 用途
accessToken 内存 接口请求 Authorization Header
refreshToken Keychain 恢复登录
user AppSession / UserStore 用户信息展示

五、后端模块结构

src/modules/auth/
├── auth.controller.ts          # 登录/刷新/登出接口
├── auth.service.ts             # 通用登录逻辑provider 调度)
├── apple-auth.service.ts       # Apple identityToken 校验
├── token.service.ts            # JWT 生成/校验
├── dto/
│   ├── dev-login.dto.ts
│   ├── apple-login.dto.ts
│   └── refresh-token.dto.ts
├── guards/
│   └── jwt-auth.guard.ts       # 全局认证守卫
├── decorators/
│   └── current-user.decorator.ts    # 从 JWT 取用户
└── strategies/
    └── jwt.strategy.ts

src/modules/users/
├── users.controller.ts         # /users/me
├── users.service.ts
└── dto/

六、业务接口安全规则

所有业务接口依赖登录体系。核心规则:不要相信前端传的 userId

GET /api/knowledge-bases
Authorization: Bearer accessToken

后端应从 JWT 拿当前用户:

// ✅ 正确:从 token 里取 currentUser.id
where: {
  userId: currentUser.id,
  deletedAt: null
}

// ❌ 错误:从请求体取 userId
where: {
  userId: body.userId
}

用户资源接口,只相信 JWT 里的 currentUser.id,不允许前端传递 userId 参数。


七、推荐开发顺序

1. Prisma 建 users / auth_accounts / refresh_tokens
2. TokenService生成 accessToken / refreshToken
3. dev-login 接口
4. JwtAuthGuard
5. CurrentUser 装饰器
6. /users/me 接口
7. iOS 接 dev-login + Keychain + AppSession
8. 知识库接口全部加 JwtAuthGuard
9. Apple 登录接口
10. refresh 接口
11. logout 接口

八、环境变量最小配置

JWT_ACCESS_SECRET=你自己的随机强密钥
JWT_REFRESH_SECRET=你自己的随机强密钥
APPLE_BUNDLE_ID=cloud.longde.AIStudyApp
APPLE_ISSUER=https://appleid.apple.com
APPLE_JWKS_URL=https://appleid.apple.com/auth/keys

九、总结

最终一句话:后端登录对接的核心不是"接 Apple 登录按钮"而是先建立自己的认证系统。Apple 登录只是其中一个 provider。先把 dev-login → token → /users/me → iOS Keychain 跑通,知识库和学习闭环就不会卡住。