OpenID Connect & OAuth2 Client

1.11.5 · active · verified Tue Apr 21

oidc-client is a comprehensive JavaScript client library for OpenID Connect (OIDC) and OAuth2, designed to facilitate secure authentication and authorization in web applications. It handles complex OAuth2 flows, including Authorization Code Flow with PKCE, implicit flow, and refresh token management, abstracting away much of the underlying protocol complexity. Developed by IdentityModel, it maintains a strong focus on security and adherence to OIDC/OAuth2 specifications. The current stable version is 1.11.5, with an active development cycle characterized by frequent bug fix releases and minor feature updates approximately every 1-2 months, as evidenced by recent patch versions. Key differentiators include its robust handling of session management, silent token renewal, and extensive configurability, making it suitable for a wide range of single-page applications and client-side integrations.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates the basic setup of UserManager for OIDC authentication, including configuration for sign-in, sign-out, and handling redirect callbacks for a Single Page Application (SPA).

import { UserManager, WebStorageStateStore, Log } from 'oidc-client';

Log.logger = console;
Log.level = Log.INFO;

const settings = {
  authority: 'https://demo.duendesoftware.com/', // Your OIDC provider authority
  client_id: 'interactive.public', // Your client ID
  redirect_uri: 'http://localhost:3000/callback', // Your app's redirect URI
  response_type: 'code',
  scope: 'openid profile api offline_access',
  post_logout_redirect_uri: 'http://localhost:3000/', // Where to go after logout
  userStore: new WebStorageStateStore({ store: window.localStorage }),
  automaticSilentRenew: true,
  // Optional: configure popup for signin/signout if needed
  // popup_redirect_uri: 'http://localhost:3000/popup.html',
  // popup_post_logout_redirect_uri: 'http://localhost:3000/popup.html',
};

const userManager = new UserManager(settings);

async function signIn() {
  try {
    await userManager.signinRedirect();
  } catch (error) {
    Log.error("Signin error", error);
  }
}

async function signOut() {
  try {
    await userManager.signoutRedirect();
  } catch (error) {
    Log.error("Signout error", error);
  }
}

async function getUser() {
  try {
    const user = await userManager.getUser();
    if (user) {
      Log.info("User loaded:", user);
      console.log('Access Token:', user.access_token);
      console.log('ID Token:', user.id_token);
    } else {
      Log.info("No user logged in.");
    }
    return user;
  } catch (error) {
    Log.error("Error getting user:", error);
    return null;
  }
}

// Example usage (e.g., in a SPA entry point)
async function initializeApp() {
  const path = window.location.pathname;
  if (path === '/callback') {
    try {
      const user = await userManager.signinRedirectCallback();
      Log.info("Signin redirect callback processed. User:", user);
      window.history.replaceState({}, document.title, '/'); // Clean up URL
    } catch (error) {
      Log.error("Error in signin redirect callback", error);
    }
  } else {
    const user = await getUser();
    if (!user) {
      console.log('No user, initiating sign-in...');
      signIn();
    } else {
      console.log('User already logged in.');
      // For demonstration purposes, you might want to call sign out later
      // setTimeout(signOut, 60000);
    }
  }
}

initializeApp();

view raw JSON →