mancala/apps/backend/README.md
Halit Aksoy 30ad51c493 feat(backend): authenticate WebSocket clients with Keycloak tokens
- New auth module verifies Keycloak access tokens offline against the
  realm's signing keys (issuer, RS256, typ=Bearer, allowed azp); guests
  are recognised by the guest realm role
- Clients send an auth message after connecting and get on_auth or
  on_auth_error; unauthenticated sockets are closed after 5 seconds and
  their messages ignored; a socket can refresh its token but not switch user
- A user can be connected from several sockets; a late close of an old
  socket no longer drops the new one
- Malformed messages are ignored instead of throwing
- Games store player names and guest flags and send them with the
  connection info
- Legacy ?userKey= clients and /register stay available behind
  LEGACY_USERKEY_AUTH; legacy keys must be UUIDs so they cannot take a
  Keycloak user's kc: id
- TypeScript target raised to es2020 for async/await
2026-10-14 01:52:07 +03:00

50 lines
1.7 KiB
Markdown

# Mancala Backend
This is the backend code for the Mancala project, written in Express.js.
## Getting Started
### Install Packages
```bash
yarn install
```
### Start in Development Mode
```bash
yarn dev
```
### Start in Release Mode
```bash
yarn build
yarn start
```
### Development Dependencies
This package depends on the local packages `@mancala/core` and `mancala.js`. Refer to their documentation for further instructions.
## Authentication
Clients log in with Keycloak (see `apps/keycloak`), either as a guest or with an account, and send the access token
over the WebSocket right after connecting:
```json
{ "channel": "auth", "message": { "token": "<Keycloak access token>" } }
```
The server answers on `on_auth` with the user (`{ id, name, isGuest }`) or on `on_auth_error` and closes the socket
with code 4001. Other messages are ignored until the socket is authenticated, and connections that do not
authenticate within 5 seconds are closed. Send `auth` again with the new token after refreshing it.
User ids of Keycloak users are the token subject prefixed with `kc:`.
| Variable | Default | Purpose |
|---|---|---|
| `KEYCLOAK_ISSUER` | `http://localhost:8080/realms/mancala` | Token issuer; must match the `iss` claim exactly |
| `KEYCLOAK_JWKS_URL` | issuer + `/protocol/openid-connect/certs` | Where to fetch signing keys, if the backend reaches Keycloak at a different address |
| `KEYCLOAK_CLIENT_IDS` | `mancala-web` | Comma-separated clients whose tokens are accepted |
| `LEGACY_USERKEY_AUTH` | `true` | Also accept old clients that connect with `?userKey=<uuid>` and the `/register` endpoint. Turn off once no released client uses it, because a userKey is not a secret the server can check |