More

Authentication

Authentication can be handled through the _onBeforeConnect lifecycle method, which acts as middleware before allowing clients to interact with your actor.


Using _onBeforeConnect

The _onBeforeConnect method is called whenever a new client attempts to connect to your actor. It takes the value of opts.parameters and returns the state to assign to the actor.

Throwing an error in _onBeforeConnect will abort the connection.

Here's a basic example:

interface State {
  // ...
}

interface ConnectionParams {
  authToken: string;
}

interface ConnectionState {
  userId: string;
  role: string;
}

class ExampleActor extends Actor<State, ConnectionParams, ConnectionState> {
  async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
    // Verify the token with your authentication system
    const userData = await myValidateAuthToken(opts.parameters.authToken);
    if (!userData) {
      throw new Error('Invalid auth token');
    }

    // Return the user data to store with the connection
    return {
      userId: userData.id,
      role: userData.role
    };
  }
}
TypeScript

Accessing Connection State

After authentication, you can access the connection state in any actor method using rpc.connection.state:

class AuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
  exampleAdminCommand(rpc: Rpc<this>) {
    // Example of validating admin access
    if (rpc.connection.state.role !== 'admin') throw new Error('User must be an admin');

    // ...
  }
}
TypeScript

Integration Examples

With API Server Authentication

interface State {
  // ...
}

interface ConnectionParams {
  apiKey: string;
}

interface ConnectionState {
  userId: string;
}

class APIAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
  async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
    // Validate API key with your server
    const response = await fetch('https://api.yourserver.com/validate', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${opts.parameters.apiKey}`
      }
    });

    if (!response.ok) {
      throw new Error('Invalid API key');
    }

    const user = await response.json();

    return {
      userId: user.id
    };
  }
}
TypeScript

When authentication fails, throwing an error in _onBeforeConnect will prevent the connection from being established, and the client will receive the error message.

With JWT Authentication

interface State {
  // ...
}

interface ConnectionParams {
  jwt: string;
}

interface ConnectionState {
  userId: string;
  permissions: string[];
}

class JwtAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
  async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
    // Verify JWT token (throws error for invalid tokens)
    const decoded = jwt.verify(opts.parameters.jwt, JWT_SECRET);

    return {
      userId: decoded.sub,
      permissions: decoded.permissions
    };
  }
}
TypeScript