# 前端认证接口变更单 ## 1. 登录响应已扩展 `POST /api/v1/auth/login` ```json { "access_token": "...", "token_type": "bearer", "expires_at": 1784260800, "refresh_token": "...", "refresh_expires_at": 1786766400 } ``` `expires_at` 和 `refresh_expires_at` 都是 Unix 秒级时间戳。前端必须把两个 token 作为同一组凭据替换,不要只更新 access token。 默认 `expires_at` 是登录或续约后 1 小时,`refresh_expires_at` 是登录或续约后 8 小时。每次续约都会同时更新两个时间;持续活动并成功续约的会话没有固定总时长上限。 ## 2. 刷新接口 `POST /api/v1/auth/refresh` 请求头: ```http Content-Type: application/json Idempotency-Key: <每次刷新新建的 UUID> ``` 请求体: ```json {"refresh_token":"<当前 refresh token>"} ``` 成功:`200 OK`,响应结构与登录完全相同,且 refresh token 已轮换。 ```bash curl -X POST http://127.0.0.1:8000/api/v1/auth/refresh \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \ -d '{"refresh_token":""}' ``` ## 3. 幂等与并发规则 - 仅在 `expires_at - now <= 1800` 且用户最近 30 分钟有点击、输入或业务操作时续约;轮询、心跳和后台请求不算用户活动。 - 一次刷新操作只生成一个 `Idempotency-Key`;超时、断网和 5xx 重试必须复用原 key 和原 refresh token。 - 同一 refresh token + 同一 key 会返回完全相同的 token 组,可安全重试。 - 同一 refresh token + 不同 key 被视为凭据重放:返回 `401 UNAUTHORIZED`,并撤销整个登录会话。 - 前端必须使用单飞机(single-flight):同一时刻只允许一个刷新请求,其他 401 请求等待该 Promise,不能各自生成 key 并发刷新。 - 成功后先原子替换凭据,再用新 access token 重放原业务请求;每个业务请求最多自动刷新一次,避免 401 死循环。 ## 4. 错误处理 - `422`:缺少/非法 `Idempotency-Key` 或请求体,是客户端错误,不要自动重试。 - `409 REFRESH_NOT_DUE`:尚未进入最后 30 分钟;保留现有凭据,可在 `details.refresh_after` 后重新评估,不要退出登录。 - `401`:refresh token 过期(连续 8 小时未成功续约)、已撤销、用户禁用/改密或检测到重放。清空两个 token 并跳转登录页。 - `5xx`/网络超时:保留原 refresh token 和原 `Idempotency-Key` 重试;收到 200 之前不要生成新 key。 ## 5. 登出 `POST /api/v1/auth/logout` 仍使用 `Authorization: Bearer `。成功后服务端同时撤销当前 access token 和 refresh token family;前端无论网络结果如何都应清空本地凭据。