1.新增退出登录的接口

This commit is contained in:
2026-05-29 14:25:59 +08:00
parent 4324c19d30
commit 4bd332a6ff
5 changed files with 138 additions and 19 deletions

View File

@@ -6,6 +6,8 @@ Scope: **platform-wide single period number and single draw result**; channels a
**Addendum (2026-04)**: §**1.5** describes server-side **Redis hot-spot caching** (`GameHotDataRedis`). It does **not** change any interface URL, parameter, or response field contracts; it is for integration testing and operations reference only.
**Addendum (2026-05)**: §**1.3** / §**1.4** / §**2.3** document **single-device login** and **`POST /api/user/logout`** (Redis-backed `device_id` binding).
## 1. Design Conventions
### 1.1 Base Conventions
@@ -64,6 +66,11 @@ Scope: **platform-wide single period number and single draw result**; channels a
### 1.3 Authentication
- **API auth (`auth-token`)**: all mobile business APIs must send header `auth-token` (issued by `/api/v1/authToken`)
- **User session (`user-token`)**: login-protected APIs send header `user-token`; on expiry, refresh or log in again
- **Single-device session (server rule)**:
- `device_id` in the `authToken` query is bound to that `auth-token` in Redis
- Each account allows **one active device** only: a successful login on a new device clears other `user-token` / `refresh_token` rows and binds the new `device_id`
- Old devices calling login-protected APIs get `code=1101` with message like “logged in on another device, please sign in again” (`lang=en` for English)
- Clients must use a **stable unique** `device_id` per install (do not randomize on every launch)
### 1.4 Obtain API Auth Token (`auth-token`)
- **GET** `/api/v1/authToken`
@@ -88,6 +95,10 @@ Response parameters:
- `expires_in`: int (TTL in seconds)
- `server_time`: int (server timestamp for clock sync)
Server behavior (single-device):
- On success, stores `device_id` for this `auth_token` in Redis with TTL = `expires_in`
- Login, login-protected HTTP APIs, and WebSocket handshake compare this `device_id` with the users active device
Possible error codes:
- `1001` missing parameter
- `1002` invalid parameter format
@@ -129,13 +140,13 @@ Possible error codes:
### 2.1 Register
- **POST** `/api/user/register`
- Purpose: phone-only registration with invite attribution (admin/channel)
- Purpose: phone-only registration with invite attribution (admin/channel); auto-login on success
- Headers: `auth-token` required (device id is taken from that tokens bound `device_id`; see §1.3)
Request parameters:
- `username`: string, phone number (registration account; mainland China mobile only)
- `password`: string, plaintext over HTTPS (login password; server stores salted hash)
- `invite_code`: string, required (sub-agent invite code; binds `channel_id` and ownership)
- `device_id`: string, optional (device id for risk control and login logs)
Response parameters:
- `user-token`: string (session token for login-protected APIs)
@@ -150,11 +161,14 @@ Response parameters:
### 2.2 Login
- **POST** `/api/user/login`
- Headers: `auth-token` required (bound `device_id` is the login device; **do not** send `device_id` in body)
Request parameters:
- `username`: string (login account; currently phone)
- `password`: string (login password)
- `device_id`: string, optional (risk assist)
Server behavior:
- On success, clears other sessions for this user and sets active device to the `auth-token`s `device_id` (§1.3)
Response parameters:
- `user-token`: string (access token for login-protected APIs)
@@ -167,7 +181,29 @@ Response parameters:
- `channel_id`: int (attribution channel id)
- `risk_flags`: int (risk status bitmask)
### 2.3 Current User Profile
### 2.3 Logout
- **POST** `/api/user/logout`
- Purpose: sign out, invalidate session, release single-device lock
Headers:
- `auth-token`: required
- `user-token`: required when logged in
Request parameters (optional):
- `refresh_token`: string (recommended; server deletes it; if omitted while logged in, server tries current session refresh token)
Response:
- `data`: empty object `{}`
Server behavior:
- Deletes current `user-token`, clears Redis active `device_id` for the user
- Deletes `refresh_token` when provided
- **Idempotent**: returns `code=1` even if already logged out (client can clear local storage)
Possible error codes:
- `1101`: missing or invalid `auth-token` (same as §1.4)
### 2.4 Current User Profile
- **POST** `/api/user/profile`
Response parameters (amount fields as 2-decimal strings, aligned with wallet display):
@@ -204,8 +240,9 @@ Response parameters (amount fields as 2-decimal strings, aligned with wallet dis
- `count`: int (pending-review withdraw orders)
- `max`: int (max pending-review withdraws per user, currently `3`; exceeds → `withdrawCreate` returns `code=2004`)
### 2.4 Refresh Token (Optional)
### 2.5 Refresh Token (Optional)
- **POST** `/api/user/refreshToken`
- Headers: `auth-token` required; active `device_id` must match (§1.3)
Request parameters:
- `refresh_token`: string (credential to renew access token)
@@ -680,7 +717,7 @@ Aligned with `app/process/GameWebSocketServer.php`, `config/process.php`, `app/c
- **Mixed content**: HTTPS pages require **`wss://`**.
- **Redis event bus**: HTTP uses **`GameWebSocketEventBus`** (Redis list); if Redis down, broadcast pushes may fail except **`admin.live.snapshot`** has per-second direct snapshot fallback.
- **Handshake auth (2026-05, mandatory)**: `GameWebSocketServer::onWebSocketConnect` via `GameWebSocketAuthHelper::authorize` on URL query:
- **mobile**: query **`auth-token`** + **`user-token`** (hyphenated; legacy `auth_token`/`user_token` parsed but **use hyphens for new clients**). Binds `user_id`; user topics only to owner.
- **mobile**: query **`auth-token`** + **`user-token`** (hyphenated; legacy `auth_token`/`user_token` parsed but **use hyphens for new clients**). Binds `user_id`; user topics only to owner. Also validates `auth-token`s bound `device_id` against the users active device (§1.3); other-device sessions are rejected.
- **admin**: query **`admin-ws-token`** (from admin `wsConfig`, Redis, TTL 7200s). `user_id=0`, full observability.
- Failure → `{"event":"ws.error","code":1101,"message":"Authentication failed: ..."}` then `close`.
- **Server filter (user topics)**: `bet.win`, `user.streak`, `wallet.changed`, `bet.accepted`, `auto.spin.progress` only if `data.user_id` equals connection `user_id`. Others broadcast by subscription. Admin mode not filtered.
@@ -811,13 +848,14 @@ Integration: `php scripts/verify_ws_topic_subscribe.php`.
## 8. Mobile End-to-End Call Flows
## 8.1 First Game Entry
1. `GET /api/v1/authToken?secret=xxx&timestamp=xxx&device_id=xxx&signature=xxx``auth-token`
2. `POST /api/user/login` (header `auth-token`)
3. `POST /api/game/lobbyInit` (header `auth-token`)
1. `GET /api/v1/authToken?secret=xxx&timestamp=xxx&device_id=xxx&signature=xxx``auth-token` (stable `device_id` per install)
2. `POST /api/user/login` (headers `auth-token`; after login also `user-token`)
3. `POST /api/game/lobbyInit` (headers `auth-token` + `user-token`)
4. WebSocket base URL (**not in lobbyInit today**: ops/bundle `H5_WEBSOCKET_URL` or custom config) → connect, **send `subscribe` immediately** (§7.0/7.1; **include `bet.win`**)
5. `POST /api/game/placeBet`
6. Balance: `placeBet.balance_after` + `wallet.changed`; after draw, **`bet.win`** (`is_win=true`), jackpot style via `data.is_jackpot` (no `user_id` in payload)
7. On disconnect/foreground, reconnect and resubscribe
8. User logout: `POST /api/user/logout` (headers `auth-token` + `user-token`, optional body `refresh_token`); clear local tokens and close WebSocket
## 8.2 Deposit → Bet → Withdraw
1. `POST /api/finance/depositTierList` (pick tier + `channels[].code`)