feat(api): 账户资料与密码安全

This commit is contained in:
R524809
2026-09-03 16:56:20 +08:00
parent 46d98ab11e
commit a5b89ddb1d
13 changed files with 552 additions and 14 deletions
+41 -5
View File
@@ -10,8 +10,10 @@
"id": "uuid",
"email": "owner@example.com",
"display_name": null,
"avatar_asset_id": null,
"email_verified_at": null,
"created_at": "2026-09-02T08:00:00Z"
"created_at": "2026-09-02T08:00:00Z",
"revision": 1
},
"workspace": {
"id": "uuid",
@@ -21,7 +23,7 @@
}
```
`email` 返回规范化后的地址;密码散列、会话哈希、手机号及任何风控信息永不返回。
`email` 返回规范化后的地址;`avatar_asset_id` 是当前头像的素材引用,普通账户响应不返回对象存储 URL。密码散列、会话哈希、手机号及任何风控信息永不返回。
## 2. 注册
@@ -50,7 +52,7 @@
"data": {
"access_token": "eyJ…",
"access_token_expires_in": 900,
"user": { "id": "uuid", "email": "owner@example.com", "display_name": "Joey", "email_verified_at": null, "created_at": "2026-09-02T08:00:00Z" },
"user": { "id": "uuid", "email": "owner@example.com", "display_name": "Joey", "avatar_asset_id": null, "email_verified_at": null, "created_at": "2026-09-02T08:00:00Z", "revision": 1 },
"workspace": { "id": "uuid", "name": "Joey 的工作空间", "role": "owner" }
}
}
@@ -86,7 +88,41 @@
要求 Bearer access token;撤销当前 refresh session、清除 refresh cookie,返回 `204 No Content`。首期不提供“退出所有设备”。
## 5. 当前用户与初始页头数据
## 5. 修改账户资料
`PATCH /api/auth/me`
Headers:`If-Match: "{revision}"` 与 `Idempotency-Key: {uuid}` 必填。
```json
{ "display_name": "Joey", "avatar_asset_id": "uuid" }
```
两个字段至少提交一个;传 `null` 可清除对应资料。成功返回 `200` 与更新后的 `user` 资源,`revision` 加一。`avatar_asset_id` 必须是当前工作空间中已完成素材校验的图片资产;接口不接受 URL、对象存储 key 或 base64 内容。版本过期返回 `409 VERSION_CONFLICT`,相同幂等键遵循统一重放规则。
头像上传复用 `POST /api/media/upload-intents` 的预签名直传和完成校验流程,并使用 `purpose: "user_avatar"`;在素材模块实现前,头像只能保持 `null`,不能以 base64 上传作为替代通道。
## 6. 修改密码
`POST /api/auth/change-password`
```json
{
"old_password": "old-strong-password",
"password": "new-strong-password",
"password_confirmation": "new-strong-password"
}
```
此接口要求 Bearer access token,并按来源 IP 和当前用户双维度限流。服务端在一个事务内锁定当前会话和用户、校验旧密码、更新密码散列、撤销该用户全部旧 session,并创建新的当前 session。成功返回 `200`、新的 `HttpOnly` refresh cookie 和:
```json
{ "data": { "access_token": "eyJ…", "access_token_expires_in": 900 } }
```
旧 access token 和其他设备的 session 会立即失效。此接口不使用 `Idempotency-Key`:密码变更及 session 轮换不能安全地将 access token 持久化为幂等回放响应;客户端收到网络中断后应以新旧密码重新登录或刷新会话,不得盲目自动重试。
## 7. 当前用户与初始页头数据
`GET /api/auth/me`
@@ -95,7 +131,7 @@
```json
{
"data": {
"user": { "id": "uuid", "email": "owner@example.com", "display_name": "Joey", "email_verified_at": null },
"user": { "id": "uuid", "email": "owner@example.com", "display_name": "Joey", "avatar_asset_id": null, "email_verified_at": null, "revision": 1 },
"workspace": { "id": "uuid", "name": "Joey 的工作空间", "role": "owner" },
"platforms": [{ "id": "uuid", "code": "OZON", "name": "Ozon" }],
"suggested_context": {