4.0 KiB
Auth — client.auth
AuthService (source: src/auth/AuthService.ts). Player authentication:
device ID login (primary for game clients), custom webhook login, logout, and
auth state observation.
Methods
loginWithDevice(options?: LoginWithDeviceOptions): Promise<LoginViaDeviceResponse>
loginWithCustom(options: LoginWithCustomOptions): Promise<LoginViaCustomResponse>
logout(): void
get isAuthenticated(): boolean
onAuthStateChange(listener: AuthStateListener): () => void
LoginWithDeviceOptions
{
region?: string; // default 'global'
language?: string; // default 'en'
nickname?: string; // omitted from the request when not set
}
The device ID is auto-generated on first call and persisted in localStorage
(src/device/DeviceId.ts). The request also carries the client's
projectKey.
LoginWithCustomOptions
{
customData: Record<string, unknown>; // required — forwarded to the project's custom auth webhook
region?: string; // default 'global'
language?: string; // default 'en'
nickname?: string;
}
Login responses
interface LoginViaDeviceResponse { accessToken?: string; refreshToken?: string }
interface LoginViaCustomResponse { accessToken?: string; refreshToken?: string }
On success both tokens are saved to the client's TokenStore, the runtime
starts (domains warmed, scenario engine restored, player_login event fired),
and the state flips to 'signed-in'.
Environments
A project has two environments, staging and prod. The SDK key you pass as
RudderClientOptions.projectKey belongs to one of them, so the environment is
resolved at login and carried inside the access and refresh tokens; nothing in
the client API takes an environment argument, and a player created in one
environment is invisible in the other. Content released only to staging is
empty for a prod key and vice versa.
Tokens issued before SDK 2.0.0 carry no environment claim and are rejected with
401. The transport's refresh then fails, clears the token store and emits
'signed-out' — log the player in again.
Auth state
type AuthState = 'signed-in' | 'signed-out';
type AuthStateListener = (state: AuthState) => void;
isAuthenticatedistruewhile an access token is present in the token store.onAuthStateChangefires the listener immediately with the current state and returns an unsubscribe function.logout()clears tokens, stops the runtime (sync poll, scenario runs, cached domain data), and emits'signed-out'.
Token refresh (automatic, transport level)
Source: src/transport/request.ts.
- Every request injects
Authorization: Bearer <accessToken>when a token exists. - On 401 the transport does a single-flight refresh against
POST /sdk/v1/authorization/refresh(concurrent 401s share one refresh) and retries the original request once. - If refresh fails, tokens are cleared,
onAuthStateChangelisteners get'signed-out', and the request throwsRudderAuthError.
TokenStore
interface TokenStore {
getAccessToken(): string | null;
getRefreshToken(): string | null;
saveTokens(accessToken: string, refreshToken: string): void;
clear(): void;
}
Factories (exported from the package root):
createDefaultTokenStore()— localStorage, with a silent in-memory fallback where localStorage is unavailable (SSR, private mode). This is the default whentokenStoreis omitted fromRudderClientOptions.createLocalStorageTokenStore()— keysrudder_access_token/rudder_refresh_token.
Provide a custom TokenStore via RudderClientOptions.tokenStore for other
backends (sessionStorage, cookies).
Errors
- Constructor: missing
baseUrl/projectKey→RudderError,code: 'sdk/invalid-options'. - Login failure →
RudderHttpError(e.g. unknown project key) orRudderNetworkError. - Any later request with an expired session →
RudderAuthError(after the refresh attempt above fails).