# 账户与会话 API > 首期只支持邮箱 + 密码。邮箱验证、密码找回、手机号、短信登录、第三方登录和 MFA 均不在本契约中。 ## 1. 数据形状 ```json { "user": { "id": "uuid", "email": "owner@example.com", "display_name": null, "avatar_asset_id": null, "email_verified_at": null, "created_at": "2026-09-02T08:00:00Z", "revision": 1 }, "workspace": { "id": "uuid", "name": "owner 的工作空间", "role": "owner" } } ``` `email` 返回规范化后的地址;`avatar_asset_id` 是当前头像的素材引用,普通账户响应不返回对象存储 URL。密码散列、会话哈希、手机号及任何风控信息永不返回。 ## 2. 注册 `POST /api/auth/register` ```json { "email": "owner@example.com", "password": "a-strong-password", "password_confirmation": "a-strong-password", "display_name": "Joey" } ``` 规则: - `email` 去除首尾空格后以不区分大小写的形式判重;必须满足基础邮箱格式。 - `password` 和确认值一致;最小长度与复杂度仍待认证安全规则确认,服务端将作为唯一校验方,前端只能展示同一规则而不能自行放宽。 - `display_name` 可选,最大 80 个字符。 - 成功时在同一事务创建 `user`、个人 `workspace` 和 `owner` membership,并创建登录会话。 成功返回 `201 Created`、`Set-Cookie` refresh token 和: ```json { "data": { "access_token": "eyJ…", "access_token_expires_in": 900, "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" } } } ``` 重复邮箱返回 `409 EMAIL_ALREADY_REGISTERED`。首期不通过“邮箱不存在/密码错误”以外的差异化响应泄露登录状态。 ## 3. 登录 `POST /api/auth/login` ```json { "email": "owner@example.com", "password": "a-strong-password" } ``` 成功响应与注册相同,刷新 token 写入新的 `HttpOnly` cookie。失败统一返回 `401 INVALID_CREDENTIALS`;禁用账户返回 `403 ACCOUNT_DISABLED`。接口应按 IP 与邮箱摘要双维度限流,但不保存明文密码或将其记入日志。 成功返回 `200 OK`、`Set-Cookie` refresh token 及上述响应体。 ## 4. 刷新与退出 `POST /api/auth/refresh` 请求不需要 body,浏览器自动携带 refresh cookie。服务端轮换 refresh token、撤销旧 session 并以 `200 OK` 返回新的短期 access token: ```json { "data": { "access_token": "eyJ…", "access_token_expires_in": 900 } } ``` 无效、过期或已撤销 refresh token 返回 `401 SESSION_EXPIRED`,并清除 refresh cookie。 `POST /api/auth/logout` 要求 Bearer access token;撤销当前 refresh session、清除 refresh cookie,返回 `204 No Content`。首期不提供“退出所有设备”。 ## 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` 返回已登录用户、首期唯一工作空间、可用平台及当前页头建议值: ```json { "data": { "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": { "platform_id": "uuid", "default_store": null } } } ``` 首期建议按平台配置顺序优先 Ozon;若该平台有默认店铺,`default_store` 返回店铺摘要,否则为 `null`。这只是页头初始建议,不在服务端建立“用户全局已选平台”状态;客户端切换平台后,在后续平台范围请求传 `X-Atlas-Platform-Id`。