JavaScript adapter for Keycloak providing OpenID Connect authentication and UMA authorization for web applications.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core authentication functionality providing login, logout, token management, and session handling for web applications integrated with Keycloak.
Creates a new Keycloak instance with server configuration.
/**
* Creates a new Keycloak authentication client
* @param config - Configuration object with server details
*/
constructor(config: KeycloakConfig);
interface KeycloakConfig {
/** Base URL of the Keycloak server */
url: string;
/** Name of the realm */
realm: string;
/** Client ID of the application */
clientId: string;
}Usage Example:
import Keycloak from "keycloak-js";
const keycloak = new Keycloak({
url: "https://auth.mycompany.com",
realm: "mycompany-realm",
clientId: "web-app"
});Initializes the Keycloak instance and determines authentication state.
/**
* Initializes Keycloak instance and checks authentication state
* @param options - Initialization options
* @returns Promise resolving to true if user is authenticated
*/
init(options?: KeycloakInitOptions): Promise<boolean>;
interface KeycloakInitOptions {
/** Action to take on load */
onLoad?: "login-required" | "check-sso";
/** Existing token for initialization */
token?: string;
/** Existing refresh token */
refreshToken?: string;
/** Existing ID token */
idToken?: string;
/** Enable login status checking via iframe */
checkLoginIframe?: boolean;
/** Interval for login status checks in seconds */
checkLoginIframeInterval?: number;
/** Response mode for authentication */
responseMode?: "query" | "fragment";
/** URI to redirect to after authentication */
redirectUri?: string;
/** URI for silent SSO checks */
silentCheckSsoRedirectUri?: string;
/** OAuth flow type */
flow?: "standard" | "implicit" | "hybrid";
/** OAuth scope parameter */
scope?: string;
/** Time difference with server in seconds */
timeSkew?: number;
/** Use nonce for security */
useNonce?: boolean;
/** Adapter type to use */
adapter?: "default" | "cordova" | "cordova-native";
/** Timeout for iframe messages in milliseconds */
messageReceiveTimeout?: number;
/** PKCE method for security */
pkceMethod?: "S256";
/** Enable debug logging */
enableLogging?: boolean;
}Usage Examples:
// Check SSO status without forcing login
const authenticated = await keycloak.init({
onLoad: "check-sso",
pkceMethod: "S256"
});
// Require login on page load
await keycloak.init({
onLoad: "login-required",
responseMode: "query",
scope: "openid profile email"
});Initiates the login process by redirecting to Keycloak login page.
/**
* Initiates login process
* @param options - Login options
* @returns Promise that resolves when login redirect occurs
*/
login(options?: KeycloakLoginOptions): Promise<void>;
interface KeycloakLoginOptions {
/** URI to redirect to after login */
redirectUri?: string;
/** OAuth scope parameter */
scope?: string;
/** Locale for login page */
locale?: string;
/** Specific identity provider to use */
idpHint?: string;
/** Login hint for pre-filling username */
loginHint?: string;
/** Action to perform (e.g., 'register') */
action?: string;
}Redirects to the Keycloak registration page.
/**
* Initiates user registration process
* @param options - Registration options
* @returns Promise that resolves when registration redirect occurs
*/
register(options?: KeycloakRegisterOptions): Promise<void>;
interface KeycloakRegisterOptions {
/** URI to redirect to after registration */
redirectUri?: string;
/** Locale for registration page */
locale?: string;
}Usage Examples:
// Simple registration
await keycloak.register();
// Registration with redirect
await keycloak.register({
redirectUri: "https://myapp.com/welcome"
});Redirects to the Keycloak account management page.
/**
* Redirects to account management page
* @param options - Account management options
* @returns Promise that resolves when redirect occurs
*/
accountManagement(options?: KeycloakAccountOptions): Promise<void>;
interface KeycloakAccountOptions {
/** URI to redirect to after account management */
redirectUri?: string;
}Usage Example:
// Open account management
await keycloak.accountManagement({
redirectUri: "https://myapp.com/profile-updated"
});Usage Examples:
// Simple login
await keycloak.login();
// Login with custom redirect
await keycloak.login({
redirectUri: "https://myapp.com/dashboard"
});
// Login with specific locale and scope
await keycloak.login({
locale: "en",
scope: "openid profile email custom-scope",
loginHint: "user@example.com"
});
// Login with identity provider hint
await keycloak.login({
idpHint: "google"
});Logs out the user and optionally redirects to a specified URL.
/**
* Logs out the user
* @param options - Logout options
* @returns Promise that resolves when logout redirect occurs
*/
logout(options?: KeycloakLogoutOptions): Promise<void>;
interface KeycloakLogoutOptions {
/** URI to redirect to after logout */
redirectUri?: string;
}Usage Examples:
// Simple logout
await keycloak.logout();
// Logout with redirect
await keycloak.logout({
redirectUri: "https://myapp.com/goodbye"
});Updates access token if it expires within specified time.
/**
* Updates token if it expires within specified time
* @param minValidity - Minimum token validity time in seconds (default: 5)
* @returns Promise resolving to true if token was refreshed
*/
updateToken(minValidity?: number): Promise<boolean>;Usage Examples:
// Update token if expires within 5 seconds
const refreshed = await keycloak.updateToken();
// Update token if expires within 30 seconds
const refreshed = await keycloak.updateToken(30);
// Use in API requests
async function makeApiCall() {
try {
await keycloak.updateToken(5);
const response = await fetch("/api/data", {
headers: {
Authorization: `Bearer ${keycloak.token}`
}
});
return response.json();
} catch (error) {
// Token refresh failed, redirect to login
await keycloak.login();
}
}Checks if the access token is expired.
/**
* Checks if access token is expired
* @param minValidity - Minimum validity time in seconds (default: 0)
* @returns True if token is expired
*/
isTokenExpired(minValidity?: number): boolean;Usage Example:
if (keycloak.isTokenExpired(30)) {
console.log("Token expires within 30 seconds");
await keycloak.updateToken(30);
}Clears all tokens from the Keycloak instance.
/**
* Clears all tokens from Keycloak instance
*/
clearToken(): void;Usage Example:
// Clear tokens on logout
keycloak.clearToken();
console.log("Tokens cleared", !keycloak.token);Loads detailed user information from the Keycloak server.
/**
* Loads user profile information from Keycloak server
* @returns Promise resolving to user profile object
*/
loadUserInfo(): Promise<any>;
/**
* Loads user profile with full user details
* @returns Promise resolving to KeycloakProfile object
*/
loadUserProfile(): Promise<KeycloakProfile>;
interface KeycloakProfile {
id?: string;
username?: string;
email?: string;
firstName?: string;
lastName?: string;
enabled?: boolean;
emailVerified?: boolean;
totp?: boolean;
createdTimestamp?: number;
attributes?: { [key: string]: string[] };
}Usage Examples:
if (keycloak.authenticated) {
// Load user info (OpenID Connect userinfo endpoint)
const userInfo = await keycloak.loadUserInfo();
console.log("User email:", userInfo.email);
console.log("User name:", userInfo.name);
// Load full user profile (Keycloak-specific)
const profile = await keycloak.loadUserProfile();
console.log("Username:", profile.username);
console.log("Created:", new Date(profile.createdTimestamp));
}/**
* Whether user is currently authenticated
*/
authenticated?: boolean;/**
* Current access token
*/
token?: string;
/**
* Current refresh token for obtaining new access tokens
*/
refreshToken?: string;
/**
* Current ID token containing user identity information
*/
idToken?: string;
/**
* Parsed access token payload as JavaScript object
*/
tokenParsed?: KeycloakTokenParsed;
/**
* Parsed ID token payload as JavaScript object
*/
idTokenParsed?: KeycloakTokenParsed;
/**
* User subject (ID) from token
*/
subject?: string;
/**
* Realm-level roles assigned to user
*/
realmAccess?: KeycloakRoles;
/**
* Resource-specific roles assigned to user
*/
resourceAccess?: KeycloakResourceAccess;
/**
* Time difference with server in seconds
*/
timeSkew?: number;
/**
* Current response mode used
*/
responseMode?: string;
/**
* Current OAuth flow type
*/
flow?: string;
/**
* Adapter type being used
*/
adapter?: string;
/**
* OAuth response type
*/
responseType?: string;
interface KeycloakTokenParsed {
exp?: number;
iat?: number;
auth_time?: number;
jti?: string;
iss?: string;
aud?: string | string[];
sub?: string;
typ?: string;
azp?: string;
session_state?: string;
realm_access?: KeycloakRoles;
resource_access?: KeycloakResourceAccess;
[key: string]: any;
}
interface KeycloakRoles {
roles: string[];
}
interface KeycloakResourceAccess {
[key: string]: KeycloakRoles;
}Usage Examples:
if (keycloak.authenticated) {
console.log("Access token:", keycloak.token);
console.log("User ID:", keycloak.subject);
console.log("Token expires at:", new Date(keycloak.tokenParsed.exp * 1000));
console.log("Realm roles:", keycloak.realmAccess?.roles);
console.log("Resource roles:", keycloak.resourceAccess);
}/**
* Called when Keycloak is ready and authentication state is determined
*/
onReady?: (authenticated: boolean) => void;
/**
* Called when user is successfully authenticated
*/
onAuthSuccess?: () => void;
/**
* Called when authentication error occurs
*/
onAuthError?: (errorData: KeycloakError) => void;
/**
* Called when token is successfully refreshed
*/
onAuthRefreshSuccess?: () => void;
/**
* Called when token refresh fails
*/
onAuthRefreshError?: () => void;
/**
* Called when user is logged out
*/
onAuthLogout?: () => void;
/**
* Called when access token expires
*/
onTokenExpired?: () => void;
interface KeycloakError {
error: string;
error_description?: string;
}Usage Examples:
// Set up event handlers
keycloak.onReady = (authenticated) => {
console.log("Keycloak ready, authenticated:", authenticated);
if (authenticated) {
loadUserDashboard();
} else {
showLoginPage();
}
};
keycloak.onAuthSuccess = () => {
console.log("User authenticated successfully");
loadUserDashboard();
};
keycloak.onAuthError = (errorData) => {
console.error("Authentication failed:", errorData.error);
showErrorMessage(errorData.error_description || "Login failed");
};
keycloak.onAuthRefreshSuccess = () => {
console.log("Token refreshed successfully");
};
keycloak.onAuthRefreshError = () => {
console.error("Token refresh failed, redirecting to login");
keycloak.login();
};
keycloak.onAuthLogout = () => {
console.log("User logged out");
redirectToHomePage();
};
keycloak.onTokenExpired = () => {
console.log("Token expired, refreshing...");
keycloak.updateToken();
};Methods for checking user roles and permissions.
/**
* Checks if user has a specific realm role
* @param role - Role name to check
* @returns True if user has the role
*/
hasRealmRole(role: string): boolean;
/**
* Checks if user has a specific resource role
* @param role - Role name to check
* @param resource - Resource name (defaults to clientId)
* @returns True if user has the role for the resource
*/
hasResourceRole(role: string, resource?: string): boolean;Usage Examples:
// Check realm roles
if (keycloak.hasRealmRole('admin')) {
console.log('User is an admin');
showAdminPanel();
}
if (keycloak.hasRealmRole('user')) {
console.log('User has basic user role');
}
// Check resource-specific roles
if (keycloak.hasResourceRole('manager', 'hr-app')) {
console.log('User is a manager in HR app');
enableManagerFeatures();
}
// Check role for current client
if (keycloak.hasResourceRole('premium-user')) {
console.log('User has premium access');
enablePremiumFeatures();
}Methods for generating Keycloak URLs for various operations.
/**
* Creates a login URL
* @param options - Login options
* @returns Login URL string
*/
createLoginUrl(options?: KeycloakLoginOptions): string;
/**
* Creates a logout URL
* @param options - Logout options
* @returns Logout URL string
*/
createLogoutUrl(options?: KeycloakLogoutOptions): string;
/**
* Creates a registration URL
* @param options - Registration options
* @returns Registration URL string
*/
createRegisterUrl(options?: KeycloakRegisterOptions): string;
/**
* Creates an account management URL
* @param options - Account options
* @returns Account management URL string
*/
createAccountUrl(options?: KeycloakAccountOptions): string;Usage Examples:
// Generate URLs for custom navigation
const loginUrl = keycloak.createLoginUrl({
redirectUri: 'https://myapp.com/dashboard',
locale: 'en'
});
const logoutUrl = keycloak.createLogoutUrl({
redirectUri: 'https://myapp.com/goodbye'
});
const registerUrl = keycloak.createRegisterUrl({
redirectUri: 'https://myapp.com/welcome'
});
const accountUrl = keycloak.createAccountUrl();
// Use URLs in custom UI
document.getElementById('login-link').href = loginUrl;
document.getElementById('logout-link').href = logoutUrl;
document.getElementById('register-link').href = registerUrl;
document.getElementById('account-link').href = accountUrl;Common error scenarios and handling patterns:
// Initialize with error handling
try {
const authenticated = await keycloak.init({
onLoad: "check-sso"
});
if (authenticated) {
// User is logged in
setupAuthenticatedApp();
} else {
// User is not logged in
setupGuestApp();
}
} catch (error) {
console.error("Keycloak initialization failed:", error);
showErrorMessage("Authentication service unavailable");
}
// Token refresh with fallback
async function secureApiCall() {
try {
await keycloak.updateToken(5);
return await fetch("/api/secure-data", {
headers: {
Authorization: `Bearer ${keycloak.token}`
}
});
} catch (error) {
if (error.message.includes("token")) {
// Token refresh failed, redirect to login
await keycloak.login();
} else {
throw error;
}
}
}