WangDL fe608da385 docs: 重构技术设计目录结构 + 更新待完成清单
- 文档从扁平结构迁移至分类目录 (api-server/ios-projects/web-projects/长期规划)
- 更新总待完成清单 (B1-B6 全部完成, I1-I7 全部完成)
- 新增后端实现状态、已实现功能汇总等已完成文档
- 新增 iOS 功能需求清单、架构设计、差距分析等文档
- 清理旧版未维护文档

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 19:08:59 +08:00

4.3 KiB
Raw Blame History

iOS 登录流程 —— iOS 端集成


一、iOS 需要的核心组件

AuthService          ← 调后端登录接口
UserService          ← 用户信息管理
TokenStore           ← token 存储协议
KeychainTokenStore   ← 基于 Keychain 的安全存储实现
AppSession           ← 管理当前登录态

二、数据存储策略

数据 存储位置 生命周期 原因
accessToken 内存 App 运行期间 短期使用,不需要持久化
refreshToken Keychain 长期持久化 敏感凭证,需安全存储,卸载后也保留
user AppSession / UserStore App 运行期间 用户展示信息

三、App 启动流程

App 启动
→ AppSession.checkSession()
→ 从 Keychain 读取 refreshToken
→ 如果没有 refreshToken
    → 进入登录页
→ 如果有 refreshToken
    → 调用 POST /api/auth/refresh
    → 成功
        → 存储新的 accessToken + refreshToken
        → 调用 GET /api/users/me
        → 存储 user 信息
        → 进入主界面
    → 失败
        → 清空 Keychain + 内存 token
        → 进入登录页

四、登录流程

开发登录dev-login

用户在登录页输入邮箱/昵称
→ AuthService.devLogin(email, nickname)
→ POST /api/auth/dev-login
→ 后端返回 { accessToken, refreshToken, user }
→ refreshToken 存 Keychain
→ accessToken 放内存
→ user 放 AppSession
→ 进入主界面

Apple 登录

用户点击 Sign in with Apple
→ iOS 系统弹出 Apple 授权界面
→ 用户授权成功
→ 拿到 identityToken + authorizationCode 等
→ AuthService.appleLogin(identityToken, ...)
→ POST /api/auth/apple
→ 后端验证 Apple token返回 { accessToken, refreshToken, user }
→ refreshToken 存 Keychain
→ accessToken 放内存
→ user 放 AppSession
→ 进入主界面

五、接口请求拦截

所有需要登录的接口都必须携带:

Authorization: Bearer {accessToken}

HTTP Client 封装建议

所有请求自动注入 Authorization Header
→ 从 AuthService 获取当前 accessToken
→ 自动添加到请求头

401 自动处理

接口返回 401
→ 调用 POST /api/auth/refresh
→ 成功
    → 更新 accessToken
    → 自动重试原请求
→ 失败
    → 清空 Keychain + 内存数据
    → 跳转登录页

重要:重试原请求时注意避免无限循环,设置最多重试 1 次。


六、退出登录

用户点击退出登录
→ AuthService.logout()
→ POST /api/auth/logout
    Body: { refreshToken: 从 Keychain 取的 refreshToken }
    Header: Authorization: Bearer accessToken
→ 后端标记 refreshToken revoked
→ iOS 端:
    → 清除 Keychain 中的 refreshToken
    → 清除内存中的 accessToken
    → 清除 AppSession 中的 user
    → 跳转登录页

七、Token 存储对比UserDefaults vs Keychain

UserDefaults Keychain
安全性 低(明文存储) 高(系统级加密)
应用卸载后 数据被清除 可选保留(推荐保留)
备份 包含在 iTunes/iCloud 备份中 仅加密备份
适用数据 非敏感偏好设置 密码、Token 等敏感凭据

结论refreshToken 一定要用 Keychain 存储。


八、Session 状态机

              App 启动
                  │
                  ▼
        ┌─────────────────┐
        │  检查 Keychain    │
        │  有 refreshToken? │
        └───────┬─────────┘
                │
        ┌───────┴───────┐
        │ 有              │ 无
        ▼                ▼
   ┌─────────┐    ┌──────────┐
   │ 调 refresh │    │ 进入登录页 │
   │ 接口      │    └──────────┘
   └─────┬─────┘
         │
    ┌────┴────┐
    │ 成功       │ 失败
    ▼           ▼
┌────────┐  ┌──────────┐
│ 调 /me  │  │ 清空数据  │
│ 进主页  │  │ 进登录页  │
└────────┘  └──────────┘