OpenID Connect (OIDC) & OAuth2 client library for TypeScript/JavaScript applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
High-level user authentication and session management with support for multiple authentication flows, automatic token renewal, and comprehensive event handling.
The primary class for managing user authentication with the OIDC/OAuth2 provider.
/**
* Provides a higher level API for signing a user in, signing out, managing user claims,
* and managing access tokens from the identity provider
*/
class UserManager {
constructor(settings: UserManagerSettings, redirectNavigator?: INavigator, popupNavigator?: INavigator, iframeNavigator?: INavigator);
/** Get the settings used to configure the UserManager */
readonly settings: UserManagerSettingsStore;
/** Get object used to register for events raised by the UserManager */
readonly events: UserManagerEvents;
/** Get object used to access the metadata configuration of the identity provider */
readonly metadataService: MetadataService;
}Standard browser redirect-based authentication flow.
/**
* Trigger a redirect of the current window to the authorization endpoint
* @param args - Optional signin arguments
* @throws Error in cases of wrong authentication
*/
signinRedirect(args?: SigninRedirectArgs): Promise<void>;
/**
* Process the response (callback) from the authorization endpoint
* @param url - The callback URL (defaults to current location)
* @returns Promise containing the authenticated User
*/
signinRedirectCallback(url?: string): Promise<User>;
interface SigninRedirectArgs extends RedirectParams, ExtraSigninRequestArgs {
// Redirect-specific parameters
}
interface RedirectParams {
/** The method used to redirect ("replace" | "assign") */
redirectMethod?: "replace" | "assign";
/** The target window being redirected ("top" | "self") */
redirectTarget?: "top" | "self";
}Usage Example:
import { UserManager } from "oidc-client-ts";
const userManager = new UserManager({
authority: "https://demo.identityserver.io",
client_id: "interactive.public",
redirect_uri: "http://localhost:5000/callback",
response_type: "code",
scope: "openid profile email api",
});
// Initiate sign-in
await userManager.signinRedirect();
// In your callback page/component
try {
const user = await userManager.signinRedirectCallback();
console.log("User signed in:", user.profile);
} catch (error) {
console.error("Sign-in failed:", error);
}Authentication using a popup window for better user experience.
/**
* Trigger a popup window to navigate to the authorization endpoint
* @param args - Optional popup signin arguments
* @returns Promise containing the authenticated User
*/
signinPopup(args?: SigninPopupArgs): Promise<User>;
/**
* Process the callback from the authorization endpoint via popup
* @param url - The callback URL (defaults to current location)
*/
signinPopupCallback(url?: string): Promise<void>;
interface SigninPopupArgs extends PopupWindowParams, ExtraSigninRequestArgs {
// Popup-specific parameters
}
interface PopupWindowParams {
/** Features parameter for window.open */
popupWindowFeatures?: PopupWindowFeatures;
/** Target parameter for window.open */
popupWindowTarget?: string;
}
interface PopupWindowFeatures {
location?: boolean;
toolbar?: boolean;
height?: number;
width?: number;
left?: number;
top?: number;
closePopupWindowAfterInSeconds?: number;
}Usage Example:
// Sign in with popup
try {
const user = await userManager.signinPopup({
popupWindowFeatures: {
height: 600,
width: 400,
location: false,
toolbar: false,
},
});
console.log("User signed in:", user.profile);
} catch (error) {
console.error("Popup sign-in failed:", error);
}Background authentication using hidden iframe for token renewal.
/**
* Trigger a silent request (via iframe) to the authorization endpoint
* @param args - Optional silent signin arguments
* @returns Promise containing the authenticated User
*/
signinSilent(args?: SigninSilentArgs): Promise<User>;
/**
* Process the callback from the authorization endpoint via iframe
* @param url - The callback URL (defaults to current location)
* @returns Promise containing the authenticated User
*/
signinSilentCallback(url?: string): Promise<User>;
interface SigninSilentArgs extends IFrameWindowParams, ExtraSigninRequestArgs {
// Silent-specific parameters
}
interface IFrameWindowParams {
/** Target origin for postMessage communication */
iframeNotifyParentOrigin?: string;
/** Script origin to validate during message callback */
iframeScriptOrigin?: string;
}Direct username/password authentication (not recommended for browser applications).
/**
* Process resource owner password credentials (ROPC) grant
* @param args - Username and password credentials
* @returns Promise containing the authenticated User
*/
signinResourceOwnerCredentials(args: SigninResourceOwnerCredentialsArgs): Promise<User>;
interface SigninResourceOwnerCredentialsArgs {
username: string;
password: string;
skipUserInfo?: boolean;
extraTokenParams?: Record<string, unknown>;
}Recommended universal callback methods that automatically detect and process any type of authentication or signout callback.
/**
* Process any signin response (callback) from the authorization endpoint.
* Automatically detects the request type and dispatches to appropriate callback handler.
* @param url - The callback URL (defaults to current location)
* @returns Promise containing the authenticated User or undefined
*/
signinCallback(url?: string): Promise<User | undefined>;
/**
* Process any signout response (callback) from the end session endpoint.
* Automatically detects the request type and dispatches to appropriate callback handler.
* @param url - The callback URL (defaults to current location)
* @param keepOpen - Whether to keep popup windows open (defaults to false)
* @returns Promise containing the signout response or undefined
*/
signoutCallback(url?: string, keepOpen?: boolean): Promise<SignoutResponse | undefined>;/**
* Trigger a redirect of the current window to the end session endpoint
* @param args - Optional signout arguments
*/
signoutRedirect(args?: SignoutRedirectArgs): Promise<void>;
/**
* Process the callback from the end session endpoint
* @param url - The callback URL (defaults to current location)
* @returns Promise containing the signout response
*/
signoutRedirectCallback(url?: string): Promise<SignoutResponse>;
interface SignoutRedirectArgs extends RedirectParams, ExtraSignoutRequestArgs {
// Redirect signout parameters
}/**
* Trigger a popup window to navigate to the end session endpoint
* @param args - Optional popup signout arguments
*/
signoutPopup(args?: SignoutPopupArgs): Promise<void>;
/**
* Process the callback from the end session endpoint via popup
* @param url - The callback URL (defaults to current location)
*/
signoutPopupCallback(url?: string): Promise<void>;
interface SignoutPopupArgs extends PopupWindowParams, ExtraSignoutRequestArgs {
// Popup signout parameters
}/**
* Trigger a silent signout via iframe
* @param args - Optional silent signout arguments
*/
signoutSilent(args?: SignoutSilentArgs): Promise<void>;
interface SignoutSilentArgs extends IFrameWindowParams, ExtraSignoutRequestArgs {
// Silent signout parameters
}/**
* Load the User object for the currently authenticated user
* @param raiseEvent - Whether to raise the UserLoaded event (default: false)
* @returns Promise containing the User or null if not authenticated
*/
getUser(raiseEvent?: boolean): Promise<User | null>;
/**
* Remove from storage the currently authenticated user
*/
removeUser(): Promise<void>;
/**
* Store a User object in the configured storage
* @param user - The User object to store
*/
storeUser(user: User): Promise<void>;/**
* Start the automatic silent renew process
*/
startSilentRenew(): void;
/**
* Stop the automatic silent renew process
*/
stopSilentRenew(): void;
/**
* Revoke the user's tokens at the authorization server
* @param types - Token types to revoke (defaults to configured types)
*/
revokeTokens(types?: RevokeTokensTypes): Promise<void>;
type RevokeTokensTypes = ("access_token" | "refresh_token")[];/**
* Query the user's session status at the identity provider
* @param args - Optional query arguments
* @returns Promise containing the session status
*/
querySessionStatus(args?: QuerySessionStatusArgs): Promise<SessionStatus>;
interface QuerySessionStatusArgs extends IFrameWindowParams, ExtraSigninRequestArgs {
// Session query parameters
}
interface SessionStatus {
/** Opaque session state used to validate if session changed */
session_state: string;
/** Subject identifier */
sub?: string;
}interface ExtraSigninRequestArgs {
/** Random value to maintain state between request and callback */
nonce?: string;
/** Additional query parameters for the authorization request */
extraQueryParams?: Record<string, string | number | boolean>;
/** Additional parameters for the token request */
extraTokenParams?: Record<string, unknown>;
/** Custom state data to round-trip */
state?: unknown;
/** Override the redirect URI */
redirect_uri?: string;
/** Space-delimited list of requested scopes */
scope?: string;
/** Prompt parameter (none, login, consent, select_account) */
prompt?: string;
/** Requested Authentication Context Class Reference values */
acr_values?: string;
/** Hint about the user for whom authentication is requested */
login_hint?: string;
/** Maximum authentication age in seconds */
max_age?: number;
/** Preferred languages for the authentication UI */
ui_locales?: string;
/** Resource indicators for the requested access token */
resource?: string | string[];
/** Custom URL state parameter */
url_state?: boolean;
}
interface ExtraSignoutRequestArgs {
/** Additional query parameters for the end session request */
extraQueryParams?: Record<string, string | number | boolean>;
/** Custom state data to round-trip */
state?: unknown;
/** ID token hint for the signout request */
id_token_hint?: string;
/** Override the post logout redirect URI */
post_logout_redirect_uri?: string;
/** Custom URL state parameter */
url_state?: boolean;
}Complete Usage Example:
import { UserManager, User } from "oidc-client-ts";
const userManager = new UserManager({
authority: "https://demo.identityserver.io",
client_id: "interactive.public",
redirect_uri: "http://localhost:5000/callback",
post_logout_redirect_uri: "http://localhost:5000",
response_type: "code",
scope: "openid profile email api",
automaticSilentRenew: true,
silent_redirect_uri: "http://localhost:5000/silent-callback.html",
});
// Set up event handling
userManager.events.addUserLoaded((user: User) => {
console.log("User loaded:", user.profile);
});
userManager.events.addUserSignedOut(() => {
console.log("User signed out");
});
// Check if user is already authenticated
const user = await userManager.getUser();
if (user && !user.expired) {
console.log("User is authenticated:", user.profile);
} else {
// Start authentication flow
await userManager.signinRedirect();
}
// Sign out
await userManager.signoutRedirect();Install with Tessl CLI
npx tessl i tessl/npm-oidc-client-ts