443c0c80ae
- 修复 notifications 模块 datetime.now() 缺少时区问题 - 用 ApiProblemError 替换 BaseService 中的 HTTPException - 更新协议文档:添加错误码、繁体字段、邀请相关协议 - 升级 Docker 镜像版本
137 lines
3.0 KiB
Markdown
137 lines
3.0 KiB
Markdown
# Session Auth Protocol (Frontend <-> Backend)
|
|
|
|
This protocol defines login, refresh, and logout contract for Eryao Flutter app.
|
|
|
|
Protocol verification status:
|
|
|
|
- Last audited against backend source: `backend/src/v1/auth/router.py`, `backend/src/v1/auth/schemas.py`, `backend/src/v1/router.py`
|
|
- Frontend mapping source: `apps/lib/features/auth/data/apis/auth_api.dart`
|
|
- Current status: aligned
|
|
|
|
## Base URL
|
|
|
|
- Runtime injected by Flutter `--dart-define=BACKEND_URL=...`
|
|
- Fallback:
|
|
- Android emulator: `http://10.0.2.2:5775`
|
|
- Others: `http://localhost:5775`
|
|
|
|
## Transport
|
|
|
|
- Content type: `application/json`
|
|
- Error format: RFC7807 with extension fields `code`, `params`
|
|
|
|
## Route audit (current backend)
|
|
|
|
From `backend/src/v1/auth/router.py`:
|
|
|
|
- `POST /auth/otp/send` (204)
|
|
- `POST /auth/email-session` (200, `SessionResponse`)
|
|
- `POST /auth/sessions/refresh` (200, `SessionResponse`)
|
|
- `DELETE /auth/sessions` (204)
|
|
|
|
Gateway error codes from `backend/src/v1/auth/gateway.py`:
|
|
|
|
- `AUTH_SERVICE_UNAVAILABLE`
|
|
- `AUTH_TOO_MANY_REQUESTS`
|
|
- `AUTH_VERIFICATION_CODE_INVALID`
|
|
- `AUTH_REFRESH_TOKEN_INVALID`
|
|
- `AUTH_REFRESH_TOKEN_MISSING`
|
|
- `AUTH_USER_NOT_FOUND`
|
|
|
|
Authorization error codes from `backend/src/v1/users/dependencies.py`:
|
|
|
|
- `AUTH_UNAUTHORIZED`
|
|
|
|
## Frontend route mapping
|
|
|
|
- Send OTP: `POST /api/v1/auth/otp/send`
|
|
- Login with OTP: `POST /api/v1/auth/email-session`
|
|
- Refresh session: `POST /api/v1/auth/sessions/refresh`
|
|
- Logout: `DELETE /api/v1/auth/sessions`
|
|
|
|
## Payload contract
|
|
|
|
### Send OTP
|
|
|
|
Request:
|
|
|
|
```json
|
|
{ "email": "user@example.com" }
|
|
```
|
|
|
|
Validation (backend):
|
|
|
|
- `email` must match `SUPABASE_EMAIL_PATTERN`
|
|
|
|
Response: `204 No Content`
|
|
|
|
### Create session
|
|
|
|
Request:
|
|
|
|
```json
|
|
{ "email": "user@example.com", "token": "123456" }
|
|
```
|
|
|
|
Validation (backend):
|
|
|
|
- `email` must match `SUPABASE_EMAIL_PATTERN`
|
|
- `token` must be exactly 6 chars
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"access_token": "...",
|
|
"refresh_token": "...",
|
|
"expires_in": 3600,
|
|
"token_type": "bearer",
|
|
"user": {
|
|
"id": "uuid",
|
|
"email": "user@example.com"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Refresh session
|
|
|
|
Request:
|
|
|
|
```json
|
|
{ "refresh_token": "..." }
|
|
```
|
|
|
|
Validation (backend):
|
|
|
|
- `refresh_token` min length: 1
|
|
|
|
Response: same as create session.
|
|
|
|
### Logout
|
|
|
|
Request:
|
|
|
|
```json
|
|
{ "refresh_token": "..." }
|
|
```
|
|
|
|
Validation (backend):
|
|
|
|
- `refresh_token` min length: 1
|
|
|
|
Response: `204 No Content`
|
|
|
|
## Global auth state requirements
|
|
|
|
- Auth must be managed by single global `AuthBloc` instance.
|
|
- App startup must attempt refresh if refresh token exists.
|
|
- On refresh failure (`401` + `AUTH_REFRESH_TOKEN_INVALID`), clear local session and route to login.
|
|
- Login success must persist access token + refresh token + display email.
|
|
- Logout must call backend route then clear local session.
|
|
- For protected requests, when backend returns `401`, frontend network layer must trigger global auth invalidation callback (single chain), not feature-level token clearing.
|
|
|
|
## Login identity mode
|
|
|
|
- Current app version supports **email OTP login only**.
|
|
- Phone registration/login is removed from frontend flow.
|