Files
eryao/docs/protocols/auth/session-auth-protocol.md
T
qzl 443c0c80ae fix: 修复后端代码违规并更新协议文档
- 修复 notifications 模块 datetime.now() 缺少时区问题
- 用 ApiProblemError 替换 BaseService 中的 HTTPException
- 更新协议文档:添加错误码、繁体字段、邀请相关协议
- 升级 Docker 镜像版本
2026-04-16 10:51:08 +08:00

3.0 KiB

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:

{ "email": "user@example.com" }

Validation (backend):

  • email must match SUPABASE_EMAIL_PATTERN

Response: 204 No Content

Create session

Request:

{ "email": "user@example.com", "token": "123456" }

Validation (backend):

  • email must match SUPABASE_EMAIL_PATTERN
  • token must be exactly 6 chars

Response:

{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 3600,
  "token_type": "bearer",
  "user": {
    "id": "uuid",
    "email": "user@example.com"
  }
}

Refresh session

Request:

{ "refresh_token": "..." }

Validation (backend):

  • refresh_token min length: 1

Response: same as create session.

Logout

Request:

{ "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.