AuthenticationRoom Authentication

Room Authentication

You can authenticate your users using the onAuth method in your room. This method is called before onJoin, and it is responsible for validating the client’s request to join a room.

  • If onAuth() returns a truthy value, onJoin() is going to be called with the returned value as the third argument.
  • If onAuth() returns a falsy value, the client is immediatelly rejected, causing the matchmaking function call from the frontend to fail.
  • You may also throw a ServerError to expose a custom error to be handled in the frontend.

With the colyseus bundle (which includes @colyseus/auth), the default static onAuth verifies the client’s JWT. A malformed or expired token is rejected with AUTH_FAILED. A client that sends no token passes through with no auth data.

⚠️

Static onAuth runs first, and short-circuits the instance onAuth. The static hook runs at matchmake time, and whatever it returns becomes client.auth. When it produced a payload (any token-bearing client), the instance onAuth is skipped entirely. Override the static onAuth when you need custom token validation; use the instance form only for rooms whose clients join without tokens.

Using @colyseus/database? The default static onAuth also enforces tokenVersion-based revocation. db.auth.ban() and db.auth.bumpTokenVersion() both reject stale tokens on the next room join. See Database → Authentication.

Server: onAuth method

The static onAuth is recommended because it does not require the room instance to be created before authenticating the client.

If you need to access the room instance during the authentication process, use the instance onAuth method.

src/rooms/MyRoom.ts
import { Room } from "colyseus";
import { JWT } from "@colyseus/auth";
 
class MyRoom extends Room {
    static async onAuth (token, options, context) {
        // validate the token
        const userdata = await JWT.verify(token);
 
        // return userdata
        return userdata;
    }
}

Server: onJoin method

Get the user data during the onJoin method via the client.auth property.

src/rooms/MyRoom.ts
import { Room } from "colyseus";
// ...
class MyRoom extends Room {
    // ...
    async onJoin (client, options, auth) {
        console.log(auth); // contains the "userdata" returned by onAuth
        console.log(client.auth); // shorthand/equivalent to `auth`
    }
}

Client SDK: Setting the auth token

The client.auth.token property is used to set the authentication token. This token will be sent as an Authorization header in all HTTP requests to the server.

client.js
// set the auth token
client.auth.token = "YOUR AUTH TOKEN";

If you are using the @colyseus/auth module, this token is managed automatically. See Authentication → Module.

Client SDK: Requesting to join a Room

Matchmaking requests will contain the auth token.

client.js
client.joinOrCreate("my_room").then((room) => {
    console.log(room);
});

With @colyseus/database

When the @colyseus/database integration is active, the default onAuth verifies the JWT and enforces tokenVersion-based revocation. Bans and explicit bumpTokenVersion() calls both reject stale tokens automatically. Override the static onAuth only for room-specific logic (for example, surfacing the ban reason in the close frame instead of a generic AUTH_FAILED). Note that overriding it replaces the default, so you re-do the token verification yourself:

src/rooms/MyRoom.ts
import { Room, ServerError } from "colyseus";
import { JWT } from "@colyseus/auth";
import { db } from "../app.config";
 
class MyRoom extends Room {
    static async onAuth(token, options, context) {
        const payload = await JWT.verify(token); // throws on invalid/expired
        const { banned, reason } = await db.auth.isBanned(payload.id);
        if (banned) {
            throw new ServerError(403, reason ?? "You are banned.");
        }
        return payload; // becomes client.auth
    }
}

onAuth Context

The third argument of the onAuth method is the context object. Both static onAuth and onAuth methods receive the same context object as the third argument.

The context object has the following properties:

  • context.token - the authentication token sent by the client.
  • context.headers - the headers sent by the client.
  • context.ip - the IP address of the client.
  • context.req - the matchmaking HTTP request, on static onAuth only.

Accessing the Auth Token

The authentication token is available in the context.token property.

src/rooms/MyRoom.ts
// ...
async onAuth(client, options, context) {
    console.log(context.token);
}
// ...

Accessing the request headers

The request headers are available in the context.headers property.

src/rooms/MyRoom.ts
// ...
async onAuth(client, options, context) {
    console.log(context.headers);
}
// ...

Accessing the client IP address

The client IP address is available in the context.ip property, as a single address. Colyseus reads it from x-real-ip, then the first entry of x-forwarded-for, then x-client-ip, and falls back to the address of the connection itself. The property is undefined when no source provides one.

src/rooms/MyRoom.ts
// ...
async onAuth(client, options, context) {
    console.log(context.ip);
}
// ...

It contains the value of the X-Real-IP header, if available. If not, it falls back to the X-Forwarded-For header, and finally to the request object’s remoteAddress property.