Move auth session persistence to true HttpOnly cookies

This commit is contained in:
Jage9
2026-02-28 04:29:57 -05:00
parent 9f7d573557
commit b8843e7c21
9 changed files with 261 additions and 85 deletions

View File

@@ -22,6 +22,7 @@ Defaults:
- Server defaults to TLS-required unless you set `network.allow_insecure_ws=true` or pass `--allow-insecure-ws` for local/dev.
- Client dev default is `localhost:5173`.
- Auth requires `CHGRID_AUTH_SECRET` in environment.
- Saved login uses server-managed `HttpOnly` cookie (`chgrid_session_token`) via `GET /auth/session/set` and `GET /auth/session/clear` (both require `X-Chgrid-Auth-Client: 1`).
## Quick Restarts

View File

@@ -87,6 +87,7 @@ This is a behavior guide for packet semantics beyond raw schemas.
- `policy` (`usernameMinLength`, `usernameMaxLength`, `passwordMinLength`, `passwordMaxLength`)
- `auth_required.authPolicy`: server auth limits advertised before login/register submit.
- `auth_result.authPolicy`: server auth limits echoed on auth success/failure responses.
- `auth_result.sessionToken` is used by the client to call server HTTP endpoint `GET /auth/session/set` (`Authorization: Bearer <sessionToken>`, `X-Chgrid-Auth-Client: 1`) so the server can issue `Set-Cookie: chgrid_session_token=...; HttpOnly`.
- `welcome.worldConfig.gridSize`: server-authoritative grid size used by clients for bounds/drawing.
- `welcome.worldConfig.movementTickMs`: server movement-rate window used for client movement pacing.
- `welcome.worldConfig.movementMaxStepsPerTick`: max allowed grid steps per movement window.
@@ -111,6 +112,10 @@ This is a behavior guide for packet semantics beyond raw schemas.
- Server is authoritative for all action validation and normalization.
- Server is authoritative for movement acceptance (bounds + rate/delta checks).
- Server persists account state (last nickname + last position) and restores spawn from that state on auth login/resume.
- Server also supports websocket handshake cookie resume:
- reads `chgrid_session_token` from websocket `Cookie` header
- attempts resume before sending `auth_required`
- exposes `GET /auth/session/clear` to expire the `HttpOnly` cookie (`X-Chgrid-Auth-Client: 1` required)
- Server applies auth hardening before accepting login/register/resume:
- login/register PBKDF2 work runs off the event loop in bounded worker concurrency
- repeated auth failures are rate-limited by IP and IP+identity windows

View File

@@ -3,15 +3,17 @@
## Connect Flow
1. User clicks connect.
2. Client validates auth form/session token and sets up local media.
2. Client validates auth form and sets up local media.
3. Client connects signaling websocket.
4. Server sends `auth_required`.
4. Server attempts cookie-based session resume from websocket handshake cookie (`chgrid_session_token`).
5. If resume does not authenticate, server sends `auth_required`.
- includes `authPolicy` limits for username/password.
5. Client sends `auth_login`, `auth_register`, or `auth_resume`.
6. Server sends `auth_result`.
6. Client sends `auth_login` or `auth_register` (or explicit `auth_resume` if provided by caller).
7. Server sends `auth_result`.
- includes role + permissions for authenticated session.
7. Server sends `welcome` with users/items snapshot.
8. Client:
8. Client persists authenticated session into a server-managed `HttpOnly` cookie via `GET /auth/session/set` (`Authorization: Bearer <sessionToken>`, `X-Chgrid-Auth-Client: 1`), and clears it via `GET /auth/session/clear` (`X-Chgrid-Auth-Client: 1`) on logout/session errors.
9. Server sends `welcome` with users/items snapshot.
10. Client:
- applies `welcome.worldConfig.gridSize` for authoritative grid bounds/rendering
- applies `welcome.worldConfig.movementTickMs` as movement pacing guidance
- applies `welcome.worldConfig.movementMaxStepsPerTick` for movement-rate parity