feat(auth): implement user and device authentication

This commit is contained in:
QiuSW
2026-07-26 15:18:48 +08:00
parent c5d3b215ff
commit 49db5b8305
66 changed files with 6216 additions and 271 deletions
+30 -5
View File
@@ -73,10 +73,10 @@ SQLite 默认文件为被忽略的 `backend-api/var/cmroubao.db`,连接启用
服务进程内自动改表;T-203 已用 `00002_tasks_and_assets.sql` 建立任务、资产、事件
和幂等记录表。
T-204 管理会话完成前,T-203 的业务路由只允许 loopback 来源,Web 写操作还校验
浏览器 Cookie 与表单字段的随机双提交 CSRF token;这不是正式登录,不能据此开放
局域网监听。模板/API handler 仍调用同一 usecase,T-204 只替换主体和会话门禁,
不重写业务规则。
T-204 已用正式服务端 session 替换临时来源门禁,不重写 T-203 业务规则。Web 写
操作校验浏览器 Cookie 与表单字段的随机双提交 CSRF token;Cookie 管理 API 写请求
校验 `X-CSRF-Token`。明文 HTTP 只能监听 loopback,非 loopback 必须配置服务端
TLS certificate/key。
### 2.2 Android App
@@ -333,7 +333,7 @@ IDLE
| `username` | UNIQUE, NOT NULL | 登录名 |
| `password_hash` | NOT NULL | 不保存明文 |
| `role` | NOT NULL | MVP 为 `ADMIN` 或 `BUYER` |
| `is_active` | NOT NULL | 禁用后不可建立新会话 |
| `is_active` | NOT NULL | 禁用后现有和新凭证均不可使用 |
| `created_at` | NOT NULL | 创建时间 |
### `devices`
@@ -345,15 +345,32 @@ IDLE
| `token_hash` | NOT NULL | 设备令牌哈希 |
| `bound_user_id` | FK, nullable | 当前绑定采购员 |
| `app_version` | nullable | App 版本 |
| `android_version` | nullable | Android 系统版本 |
| `pdd_version` | nullable | 已验证拼多多版本 |
| `last_seen_at` | nullable | 最近心跳 |
| `is_enabled` | NOT NULL | 后端开关 |
设备必须先由本地管理命令预授权。首次 BUYER 联合登录可以把 `bound_user_id` 为空的
设备原子绑定给当前采购员,不支持客户端自助重新登记或抢占其他采购员的设备。
### `admin_sessions` / `access_tokens`
- session/access token 都使用至少 256 bit 的随机 opaque secret,原值只通过
`Set-Cookie` 或登录响应返回一次,数据库只存 SHA-256。
- 管理 session 固定 8 小时绝对有效;App access token 固定 1 小时。
- 每次鉴权都联查用户/设备启用状态,因此禁用立即生效,不等待 token 到期。
- 管理 Cookie 与 App Bearer token 使用不同 middleware,不能互相替代。
- T-203 的 `local-admin` 继续作为单管理共享资源 scope;真实 `user_id` 另作 actor,
避免切换身份后隐藏已有任务。
- 管理和 App 登录在 bcrypt 前共享一个内存有界限流器,但使用独立 scope + 服务端
`RemoteAddr` 键;成功登录清零,超限返回 `429` 与 `Retry-After`。
### `purchase_tasks`
| 字段 | 约束 | 说明 |
| --- | --- | --- |
| `id` | PK | 任务 ID |
| `created_by_user_id` | FK, nullable | 新任务的真实 ADMIN actor;历史任务允许为空 |
| `title` | NOT NULL | 原始标题 |
| `description` | NOT NULL | 原始说明,可为空字符串 |
| `sku` | NOT NULL | 原始 SKU,不得由模型改写 |
@@ -367,6 +384,14 @@ IDLE
| `version` | NOT NULL | 乐观锁/状态并发控制 |
| `created_at/updated_at` | NOT NULL | 审计时间 |
### `task_events`
- 事件只追加;T-204 已实现 `TASK_CREATED`、`TASK_CANCELED`。
- `actor_user_id` 是指向 `users` 的可空外键。新管理操作必须写入真实 ADMIN,
T-203 历史事件保持为空。
- 管理任务详情 API 可返回 actor;密码、session、设备 secret 和 access token 永不
进入事件。
### `task_executions`
| 字段 | 约束 | 说明 |