74 lines
3.0 KiB
Markdown
74 lines
3.0 KiB
Markdown
# 认证模块说明(`src/auth`)
|
||
|
||
## 1. 目标
|
||
|
||
- 提供系统管理员创建、院内账号密码登录、B 端小程序手机号登录、C 端小程序手机号登录、`/me` 身份查询。
|
||
- 使用 JWT 做认证,院内账号与家属小程序账号走两套守卫。
|
||
|
||
## 2. 核心接口
|
||
|
||
- `POST /auth/system-admin`:创建系统管理员(需引导密钥)
|
||
- `POST /auth/login`:院内账号密码登录,后台与小程序均可复用
|
||
- `POST /auth/login/confirm`:院内账号密码多账号确认登录
|
||
- `POST /auth/miniapp/b/phone-login`:B 端小程序手机号登录
|
||
- `POST /auth/miniapp/b/phone-login/confirm`:B 端同手机号多账号确认登录
|
||
- `POST /auth/miniapp/c/phone-login`:C 端小程序手机号登录
|
||
- `GET /auth/me`:返回当前院内登录用户上下文
|
||
|
||
## 3. 院内账号密码登录流程
|
||
|
||
1. 前端提交 `phone + password`,`role` 与 `hospitalId` 都可以选传。
|
||
2. 若仅匹配到 1 个院内账号,后端直接返回 JWT。
|
||
3. 若匹配到多个院内账号,后端返回 `loginTicket + accounts` 候选列表。
|
||
4. 前端带 `loginTicket + userId` 调用确认接口获取最终 JWT。
|
||
## 4. 微信小程序登录流程
|
||
|
||
### B 端
|
||
|
||
1. 前端调用 `wx.login` 获取 `loginCode`。
|
||
2. 前端调用手机号授权获取 `phoneCode`。
|
||
3. 调用 `POST /auth/miniapp/b/phone-login`。
|
||
4. 若手机号仅命中 1 个院内账号,后端直接返回 JWT。
|
||
5. 若命中多个院内账号,后端返回 `loginTicket + accounts`。
|
||
6. 前端带 `loginTicket + userId` 调用确认接口拿最终 JWT。
|
||
|
||
### C 端
|
||
|
||
1. 前端同样传 `loginCode + phoneCode`。
|
||
2. 后端先校验该手机号是否已存在于 `Patient.phone`。
|
||
3. 校验通过后创建或绑定 `FamilyMiniAppAccount`,并返回 C 端 JWT。
|
||
|
||
## 5. 鉴权流程
|
||
|
||
### 院内账号
|
||
|
||
1. `AccessTokenGuard` 从 `Authorization` 读取 Bearer Token。
|
||
2. 校验 JWT 签名、`id`、`iat` 等关键载荷字段。
|
||
3. 根据 `id` 回库读取 `User` 当前角色与组织归属。
|
||
4. 校验 `iat >= user.tokenValidAfter`,保证旧 token 失效。
|
||
|
||
### 家属小程序账号
|
||
|
||
1. `FamilyAccessTokenGuard` 从 `Authorization` 读取 Bearer Token。
|
||
2. 校验 C 端 token 的 `id + type=FAMILY_MINIAPP`。
|
||
3. 根据 `id` 回库读取 `FamilyMiniAppAccount`。
|
||
4. 将家属账号上下文注入 `request.familyActor`。
|
||
|
||
## 6. 环境变量
|
||
|
||
- `AUTH_TOKEN_SECRET`
|
||
- `SYSTEM_ADMIN_BOOTSTRAP_KEY`
|
||
- `WECHAT_MINIAPP_APPID`
|
||
- `WECHAT_MINIAPP_SECRET`
|
||
|
||
## 7. 关键规则
|
||
|
||
- 后台 Web 与 B 端小程序都可以复用 `POST /auth/login` 做账号密码登录。
|
||
- 密码登录命中多个院内账号时,不再强制前端手填 `hospitalId`,改为后端返回候选账号供选择。
|
||
- B 端小程序登录复用 `User` 表,继续使用 `openId`。
|
||
- B 端账号未绑定 `openId` 时,首次小程序登录自动绑定。
|
||
- 同一个 `openId` 不能绑定多个院内账号。
|
||
- C 端家属账号独立存放在 `FamilyMiniAppAccount`。
|
||
- C 端手机号必须先存在于患者档案,否则拒绝登录。
|
||
- `serviceUid` 仅预留字段,本次不提供绑定接口。
|