Convert Figma logo to code with AI

panva logoopenid-client

OAuth 2 / OpenID Connect Client API for JavaScript Runtimes

1,818
390
1,818
0

Top Related Projects

22,126

Open Source Identity and Access Management For Modern Applications and Services

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core

22,914

Simple, unobtrusive authentication for Node.js.

Microsoft Authentication Library (MSAL) for JS

iOS and macOS SDK for communicating with OAuth 2.0 and OpenID Connect providers.

Quick Overview

panva/openid-client is a certified OpenID Connect and OAuth 2.0 client library for Node.js. It provides a robust implementation of the OpenID Connect and OAuth 2.0 protocols, allowing developers to easily integrate authentication and authorization into their applications.

Pros

  • Fully certified OpenID Connect Relying Party implementation
  • Supports various OAuth 2.0 and OpenID Connect flows
  • Extensive documentation and examples
  • Active maintenance and community support

Cons

  • Steep learning curve for beginners unfamiliar with OAuth 2.0 and OpenID Connect
  • Limited built-in support for specific identity providers (requires manual configuration)
  • Primarily focused on server-side implementations

Code Examples

  1. Creating an Issuer instance:
const { Issuer } = require('openid-client');

const googleIssuer = await Issuer.discover('https://accounts.google.com');
console.log('Discovered issuer %s %O', googleIssuer.issuer, googleIssuer.metadata);
  1. Creating a client instance:
const client = new googleIssuer.Client({
  client_id: 'your_client_id',
  client_secret: 'your_client_secret',
  redirect_uris: ['http://localhost:3000/cb'],
  response_types: ['code'],
});
  1. Initiating an authentication request:
const authorizationUrl = client.authorizationUrl({
  scope: 'openid email profile',
  state: 'some-random-state-value',
});

// Redirect the user to authorizationUrl
  1. Handling the callback and token exchange:
const params = client.callbackParams(req);
const tokenSet = await client.callback('http://localhost:3000/cb', params, { state: 'some-random-state-value' });

console.log('Received and validated tokens %j', tokenSet);
console.log('Validated ID Token claims %j', tokenSet.claims());

Getting Started

  1. Install the library:

    npm install openid-client
    
  2. Import and use the library in your code:

    const { Issuer, generators } = require('openid-client');
    
    // Discover the OpenID Provider
    const issuer = await Issuer.discover('https://your-identity-provider.com');
    
    // Create a client instance
    const client = new issuer.Client({
      client_id: 'your_client_id',
      client_secret: 'your_client_secret',
      redirect_uris: ['http://localhost:3000/cb'],
      response_types: ['code'],
    });
    
    // Use the client for authentication and token management
    

Competitor Comparisons

22,126

Open Source Identity and Access Management For Modern Applications and Services

Pros of Keycloak

  • Comprehensive identity and access management solution with a full-featured admin console
  • Supports multiple protocols including OpenID Connect, OAuth 2.0, and SAML
  • Offers user federation, identity brokering, and social login out of the box

Cons of Keycloak

  • Heavier and more complex to set up and maintain compared to a lightweight client library
  • Requires more resources to run as it's a full-fledged server application
  • May be overkill for simple authentication needs in smaller applications

Code Comparison

Keycloak (Java):

KeycloakBuilder.builder()
    .serverUrl("https://auth-server/auth")
    .realm("myrealm")
    .clientId("myclient")
    .clientSecret("secret")
    .build();

openid-client (JavaScript):

const client = await Issuer.discover('https://auth-server/.well-known/openid-configuration')
  .then(issuer => new issuer.Client({
    client_id: 'myclient',
    client_secret: 'secret'
  }));

Keycloak provides a more comprehensive solution for identity management, while openid-client offers a lightweight client library for OpenID Connect. Keycloak is better suited for complex enterprise scenarios, whereas openid-client is ideal for simpler authentication needs in JavaScript applications.

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core

Pros of IdentityServer4

  • Full-featured OpenID Connect and OAuth 2.0 framework for ASP.NET Core
  • Extensive documentation and community support
  • Highly customizable with built-in UI for common identity workflows

Cons of IdentityServer4

  • Steeper learning curve due to its comprehensive feature set
  • Requires more setup and configuration compared to simpler libraries
  • Primarily focused on .NET ecosystem, limiting cross-platform usage

Code Comparison

IdentityServer4 (C#):

services.AddIdentityServer()
    .AddInMemoryClients(Config.Clients)
    .AddInMemoryIdentityResources(Config.IdentityResources)
    .AddInMemoryApiResources(Config.ApiResources)
    .AddTestUsers(Config.TestUsers)
    .AddDeveloperSigningCredential();

openid-client (JavaScript):

const client = await Issuer.discover('https://example.com')
  .then(issuer => new issuer.Client({
    client_id: 'client_id',
    client_secret: 'client_secret',
    redirect_uris: ['http://localhost:3000/cb'],
    response_types: ['code'],
  }));

While IdentityServer4 provides a comprehensive identity solution for .NET applications, openid-client offers a lightweight and flexible OpenID Connect client for Node.js. IdentityServer4 is better suited for complex enterprise scenarios, while openid-client is ideal for simpler implementations or when working in a JavaScript environment.

22,914

Simple, unobtrusive authentication for Node.js.

Pros of Passport

  • Extensive ecosystem with numerous strategies for various authentication methods
  • Well-established and widely adopted in the Node.js community
  • Flexible middleware-based architecture for easy integration

Cons of Passport

  • Can be complex to set up and configure for specific use cases
  • May require additional packages for OpenID Connect support
  • Less focused on OpenID Connect specifics compared to openid-client

Code Comparison

openid-client:

const client = new Issuer.Client({
  client_id: 'client_id',
  client_secret: 'client_secret',
  redirect_uris: ['http://localhost:3000/cb'],
  response_types: ['code'],
});

const authorizationUrl = client.authorizationUrl({
  scope: 'openid email profile',
  state: 'some-state-value',
});

Passport:

passport.use(new OpenIDStrategy({
    issuer: 'https://server.example.com',
    clientID: 'client_id',
    clientSecret: 'client_secret',
    callbackURL: 'http://localhost:3000/cb'
  },
  function(iss, sub, profile, done) {
    // Verification callback
  }
));

openid-client focuses specifically on OpenID Connect implementation, providing a more streamlined approach for OIDC-specific use cases. Passport, on the other hand, offers a broader authentication framework with support for various strategies, including OpenID Connect through additional packages.

Microsoft Authentication Library (MSAL) for JS

Pros of microsoft-authentication-library-for-js

  • Specifically designed for Azure AD and Microsoft identity platform
  • Extensive documentation and support from Microsoft
  • Seamless integration with other Microsoft services and APIs

Cons of microsoft-authentication-library-for-js

  • Limited to Microsoft identity providers
  • Larger package size and potentially more complex setup
  • May have a steeper learning curve for developers not familiar with Microsoft ecosystem

Code Comparison

microsoft-authentication-library-for-js:

const msalConfig = {
    auth: {
        clientId: "your_client_id",
        authority: "https://login.microsoftonline.com/your_tenant_id"
    }
};
const msalInstance = new msal.PublicClientApplication(msalConfig);

openid-client:

const client = await Issuer.discover('https://server.example.com')
    .then(issuer => new issuer.Client({
        client_id: 'your_client_id',
        client_secret: 'your_client_secret'
    }));

The microsoft-authentication-library-for-js example shows configuration specific to Azure AD, while openid-client demonstrates a more generic OpenID Connect setup. openid-client offers more flexibility for different identity providers but requires more manual configuration. microsoft-authentication-library-for-js provides a more streamlined experience for Microsoft-specific authentication scenarios.

iOS and macOS SDK for communicating with OAuth 2.0 and OpenID Connect providers.

Pros of AppAuth-iOS

  • Specifically designed for iOS, providing native integration and optimized performance
  • Includes built-in support for iOS-specific features like ASWebAuthenticationSession
  • Offers a more comprehensive SDK with additional tools for iOS app development

Cons of AppAuth-iOS

  • Limited to iOS platform, lacking cross-platform compatibility
  • May have a steeper learning curve for developers not familiar with iOS development
  • Less frequent updates compared to openid-client

Code Comparison

AppAuth-iOS (Objective-C):

OIDAuthorizationRequest *request = [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
                                                                                 clientId:clientID
                                                                                   scopes:@[OIDScopeOpenID, OIDScopeProfile]
                                                                              redirectURL:redirectURI
                                                                             responseType:OIDResponseTypeCode
                                                                     additionalParameters:nil];

openid-client (JavaScript):

const client = new Client({
  client_id: 'client_id',
  client_secret: 'client_secret',
  redirect_uris: ['http://localhost:3000/cb'],
  response_types: ['code'],
});

Both libraries provide methods for creating authorization requests, but AppAuth-iOS offers more iOS-specific configuration options, while openid-client provides a more concise and flexible approach suitable for various platforms.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

openid-client

OAuth 2 / OpenID Connect Client API for JavaScript Runtimes

openid-client simplifies integration with authorization servers by providing easy-to-use APIs for the most common authentication and authorization flows, including OAuth 2 and OpenID Connect. It is designed for JavaScript runtimes like Node.js, Browsers, Deno, Cloudflare Workers, and more.

Features

The following features are currently in scope and implemented in this software:

  • Authorization Server Metadata discovery
  • Authorization Code Flow (profiled under OpenID Connect 1.0, OAuth 2.0, OAuth 2.1, FAPI 1.0 Advanced, and FAPI 2.0)
  • Refresh Token, Device Authorization, and Client Credentials Grants
  • Demonstrating Proof-of-Possession at the Application Layer (DPoP)
  • Token Introspection and Revocation
  • Pushed Authorization Requests (PAR)
  • UserInfo and Protected Resource Requests
  • Authorization Server Issuer Identification
  • JWT Secured Introspection, Response Mode (JARM), Authorization Request (JAR), and UserInfo
  • Passport Strategy

Sponsor

Auth0 by Okta

If you want to quickly add authentication to JavaScript apps, feel free to check out Auth0's JavaScript SDK and free plan. Create an Auth0 account; it's free!

Certification

OpenID Certification

Filip Skokan has certified that this software conforms to the Basic, FAPI 1.0, and FAPI 2.0 Relying Party Conformance Profiles of the OpenID Connect™ protocol.

💗 Help the project

Support from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by becoming a sponsor.

API Reference Documentation

openid-client is distributed via npmjs.com and github.com.

Examples

example ESM import

import * as client from 'openid-client'
  • Authorization Code Flow (OAuth 2.0) - source
  • Authorization Code Flow (OpenID Connect) - source | diff
  • Extensions
    • JWT Secured Authorization Request (JAR) - source | diff
    • JWT Secured Authorization Response Mode (JARM) - source | diff
    • Pushed Authorization Request (PAR) - source | diff
  • Passport Strategy - source

Quick start

let server!: URL // Authorization Server's Issuer Identifier
let clientId!: string // Client identifier at the Authorization Server
let clientSecret!: string // Client Secret

let config: client.Configuration = await client.discovery(
  server,
  clientId,
  clientSecret,
)

Authorization Code Flow

Authorization Code flow is for obtaining Access Tokens (and optionally Refresh Tokens) to use with third party APIs.

When you want to have your end-users authorize or authenticate you need to send them to the authorization server's authorization_endpoint. Consult the web framework of your choice on how to redirect but here's how to get the authorization endpoint's URL with parameters already encoded in the query to redirect to.

/**
 * Value used in the authorization request as the redirect_uri parameter, this
 * is typically pre-registered at the Authorization Server.
 */
let redirect_uri!: string
let scope!: string // Scope of the access request
/**
 * PKCE: The following MUST be generated for every redirect to the
 * authorization_endpoint. You must store the code_verifier and state in the
 * end-user session such that it can be recovered as the user gets redirected
 * from the authorization server back to your application.
 */
let code_verifier: string = client.randomPKCECodeVerifier()
let code_challenge: string =
  await client.calculatePKCECodeChallenge(code_verifier)
let state!: string

let parameters: Record<string, string> = {
  redirect_uri,
  scope,
  code_challenge,
  code_challenge_method: 'S256',
}

if (!config.serverMetadata().supportsPKCE()) {
  /**
   * We cannot be sure the server supports PKCE so we're going to use state too.
   * Use of PKCE is backwards compatible even if the AS doesn't support it which
   * is why we're using it regardless. Like PKCE, random state must be generated
   * for every redirect to the authorization_endpoint.
   */
  state = client.randomState()
  parameters.state = state
}

let redirectTo: URL = client.buildAuthorizationUrl(config, parameters)

// now redirect the user to redirectTo.href
console.log('redirecting to', redirectTo.href)

When end-users are redirected back to the redirect_uri your application consumes the callback and passes in PKCE code_verifier to include it in the authorization code grant token exchange.

let getCurrentUrl!: (...args: any) => URL

let tokens: client.TokenEndpointResponse = await client.authorizationCodeGrant(
  config,
  getCurrentUrl(),
  {
    pkceCodeVerifier: code_verifier,
    expectedState: state,
  },
)

console.log('Token Endpoint Response', tokens)

You can then fetch a protected resource response

let protectedResourceResponse: Response = await client.fetchProtectedResource(
  config,
  tokens.access_token,
  new URL('https://rs.example.com/api'),
  'GET',
)

console.log(
  'Protected Resource Response',
  await protectedResourceResponse.json(),
)

Device Authorization Grant (Device Flow)

let scope!: string // Scope of the access request

let response = await client.initiateDeviceAuthorization(config, { scope })

console.log('User Code:', response.user_code)
console.log('Verification URI:', response.verification_uri)
console.log('Verification URI (complete):', response.verification_uri_complete)

You will display the instructions to the end-user and have them directed at verification_uri or verification_uri_complete, afterwards you can start polling for the Device Access Token Response.

let tokens: client.TokenEndpointResponse =
  await client.pollDeviceAuthorizationGrant(config, response)

console.log('Token Endpoint Response', tokens)

This will poll in a regular interval and only resolve with tokens once the end-user authenticates.

Client Credentials Grant

Client Credentials flow is for obtaining Access Tokens to use with third party APIs on behalf of your application, rather than an end-user which was the case in previous examples.

let scope!: string // Scope of the access request
let resource!: string // Resource Indicator of the Resource Server the access token is for

let tokens: client.TokenEndpointResponse = await lib.clientCredentialsGrant(
  config,
  { scope, resource },
)

console.log('Token Endpoint Response', tokens)

Supported Runtimes

The supported JavaScript runtimes include those that support the utilized Web API globals and standard built-in objects. These are (but are not limited to):

  • Browsers
  • Bun
  • Cloudflare Workers
  • Deno
  • Electron
  • Node.js1
  • Vercel's Edge Runtime

Supported Versions

VersionSecurity Fixes 🔑Other Bug Fixes 🐞New Features ⭐Runtime and Module type
v6.x✅✅✅Universal2 ESM3
v5.x✅❌❌Node.js CJS + ESM

Footnotes

  1. Node.js v20.x as baseline is required

  2. Assumes runtime support of WebCryptoAPI and Fetch API

  3. CJS style require('openid-client') is possible in Node.js versions where process.features.require_module is true or with the --experimental-require-module Node.js CLI flag.

NPM DownloadsLast 30 Days