Public Access
feat(login): cookie session with rotating refresh token
The login token moves out of localStorage into an HttpOnly cookie (15 min), so a script on the page can no longer read it. A random refresh token (30 days, sliding) renews it; only its SHA-256 is stored. Each refresh replaces the token, and a replaced token that comes back revokes every token of that login. Unsafe requests need an X-TBP-Client or Authorization header, and CORS allows only the exact frontend origin. A missing or expired token now answers 401 instead of 403, so the frontend can refresh.
This commit is contained in:
1 parent
600b0b143f
commit
930e08e6dd
30 files changed
+1096
-151
No files matched your search
@@ -20,6 +20,12 @@ To Be Played is split into three repositories:
|
||||
- JWT signed with **EdDSA (Ed25519)**. Auth holds the private key, Core only the public key, so Core can verify
|
||||
tokens but never create them. Tokens carry a `kid` header, and `GET /.well-known/jwks.json` publishes the
|
||||
public key as a JWK, so Core finds the right key after a rotation.
|
||||
- Session in two HttpOnly cookies, so no script on the page can read a token. The access token lives 15 minutes in
|
||||
`tbp_access` (sent to Auth and Core). The refresh token is random, lives 30 days from its last use in
|
||||
`tbp_refresh` (sent to `/api/auth` only) and is stored only as a SHA-256 hash. Each refresh replaces it; a replaced
|
||||
token that comes back revokes all tokens of that login. Logout revokes them too.
|
||||
- CSRF guard: `POST`, `PUT` and `DELETE` need an `X-TBP-Client` or `Authorization` header, and CORS allows only the
|
||||
frontend origin. A `Bearer` header still works for API clients and tests.
|
||||
- User settings: display name (unique, case-insensitive), Steam ID, language, dark mode.
|
||||
- Appearance settings synced across devices: accent color, corner style, wide layout, background and dashboard
|
||||
banner from the user's own game art. Only whitelisted presets and Steam app ids are stored, never raw CSS or URLs.
|
||||
@@ -32,10 +38,12 @@ To Be Played is split into three repositories:
|
||||
| Method | Path | Auth |
|
||||
|---|---|---|
|
||||
| `POST` | `/api/registration/new` | public |
|
||||
| `POST` | `/api/auth/login` | public |
|
||||
| `GET` | `/api/users/me` | JWT |
|
||||
| `PUT` | `/api/users/settings` | JWT |
|
||||
| `PUT` | `/api/users/settings/appearance` | JWT |
|
||||
| `POST` | `/api/auth/login` | public, sets both cookies |
|
||||
| `POST` | `/api/auth/refresh` | refresh cookie, replaces both cookies |
|
||||
| `POST` | `/api/auth/logout` | refresh cookie, clears both cookies |
|
||||
| `GET` | `/api/users/me` | access token |
|
||||
| `PUT` | `/api/users/settings` | access token, sets a new access cookie |
|
||||
| `PUT` | `/api/users/settings/appearance` | access token |
|
||||
| `GET` | `/api/public/profiles/{displayName}` | public |
|
||||
| `GET` | `/api/stats/public` | public |
|
||||
|
||||
@@ -76,6 +84,11 @@ Needs Java 25 and Docker.
|
||||
Spring Boot's Docker Compose support starts PostgreSQL from `compose.yaml`, Flyway applies the migrations, and the
|
||||
service listens on `http://localhost:8080`. Health: `/actuator/health`, metrics: `/actuator/prometheus`.
|
||||
|
||||
The cookies are host-only unless `APP_AUTH_COOKIE_DOMAIN` is set; production sets it to the parent domain, so Core
|
||||
gets the access cookie too. Browsers accept `Secure` cookies on `http://localhost`, so local development needs no
|
||||
cookie settings. Open the frontend on `localhost` (not `127.0.0.1`), so the browser sends the cookies to every
|
||||
local port.
|
||||
|
||||
Configuration comes from environment variables:
|
||||
|
||||
| Variable | Purpose |
|
||||
@@ -103,8 +116,6 @@ Runs unit, WebMvc, persistence and integration tests plus the ArchUnit rules. Ne
|
||||
|
||||
## Roadmap
|
||||
|
||||
- Short-lived access token plus rotating refresh token in an httpOnly cookie, with CSRF protection. Today the token
|
||||
lives 24 h in `localStorage` and cannot be revoked.
|
||||
- Account deletion and data export.
|
||||
|
||||
## License
|
||||
|
||||
Reference in new issue
Block a user