Gathering detailed insights and metrics for openid-client
Gathering detailed insights and metrics for openid-client
Gathering detailed insights and metrics for openid-client
Gathering detailed insights and metrics for openid-client
OAuth 2 / OpenID Connect Client API for JavaScript Runtimes
npm install openid-client
Typescript
Module System
Node Version
NPM Version
98.7
Supply Chain
100
Quality
91.7
Maintenance
100
Vulnerability
100
License
TypeScript (92.46%)
JavaScript (4.98%)
Shell (2.56%)
Total Downloads
332,969,765
Last Day
158,816
Last Week
3,039,110
Last Month
12,799,601
Last Year
132,170,442
MIT License
2,084 Stars
1,063 Commits
405 Forks
29 Watchers
3 Branches
41 Contributors
Updated on Jun 15, 2025
Minified
Minified + Gzipped
Latest Version
6.5.1
Package Id
openid-client@6.5.1
Unpacked Size
196.43 kB
Size
38.36 kB
File Count
9
NPM Version
10.9.2
Node Version
22.15.0
Published on
Jun 08, 2025
Cumulative downloads
Total Downloads
Last Day
7%
158,816
Compared to previous day
Last Week
-4.9%
3,039,110
Compared to previous week
Last Month
1.1%
12,799,601
Compared to previous month
Last Year
38.7%
132,170,442
Compared to previous year
2
28
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.
The following features are currently in scope and implemented in this software:
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!
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.
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.
openid-client
is distributed via npmjs.com, jsr.io, and github.com.
example
ESM import1
1import * as client from 'openid-client'
1let server!: URL // Authorization Server's Issuer Identifier 2let clientId!: string // Client identifier at the Authorization Server 3let clientSecret!: string // Client Secret 4 5let config: client.Configuration = await client.discovery( 6 server, 7 clientId, 8 clientSecret, 9)
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.
1/** 2 * Value used in the authorization request as the redirect_uri parameter, this 3 * is typically pre-registered at the Authorization Server. 4 */ 5let redirect_uri!: string 6let scope!: string // Scope of the access request 7/** 8 * PKCE: The following MUST be generated for every redirect to the 9 * authorization_endpoint. You must store the code_verifier and state in the 10 * end-user session such that it can be recovered as the user gets redirected 11 * from the authorization server back to your application. 12 */ 13let code_verifier: string = client.randomPKCECodeVerifier() 14let code_challenge: string = 15 await client.calculatePKCECodeChallenge(code_verifier) 16let state!: string 17 18let parameters: Record<string, string> = { 19 redirect_uri, 20 scope, 21 code_challenge, 22 code_challenge_method: 'S256', 23} 24 25if (!config.serverMetadata().supportsPKCE()) { 26 /** 27 * We cannot be sure the server supports PKCE so we're going to use state too. 28 * Use of PKCE is backwards compatible even if the AS doesn't support it which 29 * is why we're using it regardless. Like PKCE, random state must be generated 30 * for every redirect to the authorization_endpoint. 31 */ 32 state = client.randomState() 33 parameters.state = state 34} 35 36let redirectTo: URL = client.buildAuthorizationUrl(config, parameters) 37 38// now redirect the user to redirectTo.href 39console.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.
1let getCurrentUrl!: (...args: any) => URL 2 3let tokens: client.TokenEndpointResponse = await client.authorizationCodeGrant( 4 config, 5 getCurrentUrl(), 6 { 7 pkceCodeVerifier: code_verifier, 8 expectedState: state, 9 }, 10) 11 12console.log('Token Endpoint Response', tokens)
You can then fetch a protected resource response
1let protectedResourceResponse: Response = await client.fetchProtectedResource(
2 config,
3 tokens.access_token,
4 new URL('https://rs.example.com/api'),
5 'GET',
6)
7
8console.log(
9 'Protected Resource Response',
10 await protectedResourceResponse.json(),
11)
1let scope!: string // Scope of the access request 2 3let response = await client.initiateDeviceAuthorization(config, { scope }) 4 5console.log('User Code:', response.user_code) 6console.log('Verification URI:', response.verification_uri) 7console.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.
1let tokens: client.TokenEndpointResponse = 2 await client.pollDeviceAuthorizationGrant(config, response) 3 4console.log('Token Endpoint Response', tokens)
This will poll in a regular interval and only resolve with tokens once the end-user authenticates.
1let scope!: string // Scope of the access request
2/**
3 * One of login_hint, id_token_hint, or login_hint_token parameters must be
4 * provided in CIBA
5 */
6let login_hint!: string
7
8let response = await client.initiateBackchannelAuthentication(config, {
9 scope,
10 login_hint,
11})
12
13/**
14 * OPTIONAL: If your client is configured with Ping Mode you'd invoke the
15 * following after getting the CIBA Ping Callback (its implementation is
16 * framework specific and therefore out of scope for openid-client)
17 */
18
19let tokens: client.TokenEndpointResponse =
20 await client.pollBackchannelAuthenticationGrant(config, response)
21
22console.log('Token Endpoint Response', tokens)
This will poll in a regular interval and only resolve with tokens once the end-user authenticates.
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.
1let scope!: string // Scope of the access request
2let resource!: string // Resource Indicator of the Resource Server the access token is for
3
4let tokens: client.TokenEndpointResponse = await lib.clientCredentialsGrant(
5 config,
6 { scope, resource },
7)
8
9console.log('Token Endpoint Response', tokens)
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):
Version | Security Fixes 🔑 | Other Bug Fixes 🐞 | New Features ⭐ | Runtime and Module type |
---|---|---|---|---|
v6.x | Security Policy | ✅ | ✅ | Universal3 ESM1 |
v5.x | Security Policy | ❌ | ❌ | Node.js CJS + ESM |
No vulnerabilities found.
No security vulnerabilities found.