Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
openid-client
Advanced tools
OpenID Connect Relying Party (RP, Client) implementation for Node.js runtime, supports passportjs
The openid-client package is a server-side library that allows Node.js applications to act as a Relying Party (RP) for any OpenID Connect (OIDC) compliant Identity Provider (IP). It provides functionality to discover OIDC providers, authenticate users, validate ID tokens, and securely perform token operations.
Discovery of OpenID Provider configuration
This feature allows the client to automatically discover the OpenID Provider's configuration using the issuer's URL. It simplifies the process of setting up the client by fetching the necessary endpoints and public keys.
const { Issuer } = require('openid-client');
(async () => {
const googleIssuer = await Issuer.discover('https://accounts.google.com');
console.log('Discovered issuer %s', googleIssuer.issuer);
})();
Client authentication with an OpenID Provider
This code sample demonstrates how to authenticate with an OpenID Provider by creating a client instance with the necessary credentials and generating an authorization URL for user redirection.
const { Issuer } = require('openid-client');
(async () => {
const issuer = await Issuer.discover('https://example.com');
const client = new issuer.Client({
client_id: 'your-client-id',
client_secret: 'your-client-secret',
redirect_uris: ['https://your-callback-url/callback'],
response_types: ['code']
});
const authorizationUrl = client.authorizationUrl({
scope: 'openid email profile',
});
console.log('Authorization URL:', authorizationUrl);
})();
Handling authentication responses
This feature is used to handle the callback from the OpenID Provider after user authentication. It involves parsing the callback parameters, exchanging the authorization code for tokens, and validating the ID token.
const { Issuer, generators } = require('openid-client');
(async () => {
const issuer = await Issuer.discover('https://example.com');
const client = new issuer.Client({
client_id: 'your-client-id',
client_secret: 'your-client-secret',
redirect_uris: ['https://your-callback-url/callback'],
response_types: ['code']
});
const code_verifier = generators.codeVerifier();
const code_challenge = generators.codeChallenge(code_verifier);
const params = client.callbackParams('https://your-callback-url/callback?code=AUTH_CODE&state=STATE');
const tokenSet = await client.callback('https://your-callback-url/callback', params, { code_verifier });
console.log('Received and validated tokens %j', tokenSet);
console.log('ID Token claims %j', tokenSet.claims());
})();
Token management
This code sample shows how to manage tokens, including how to exchange an authorization code for tokens and how to refresh tokens using a refresh token.
const { Issuer } = require('openid-client');
(async () => {
const issuer = await Issuer.discover('https://example.com');
const client = new issuer.Client({
client_id: 'your-client-id',
client_secret: 'your-client-secret'
});
const tokenSet = await client.grant({
grant_type: 'authorization_code',
code: 'AUTH_CODE',
redirect_uri: 'https://your-callback-url/callback'
});
const refreshedTokenSet = await client.refresh(tokenSet.refresh_token);
console.log('Refreshed tokens %j', refreshedTokenSet);
})();
Passport is a widely used authentication middleware for Node.js. It supports a wide range of strategies, including OpenID Connect. Compared to openid-client, Passport provides a more general authentication solution that can be extended with various strategies for different authentication mechanisms.
oidc-provider is a Node.js library that allows developers to implement their own OpenID Connect Provider. It is different from openid-client, which is designed to be used as a client for existing providers. oidc-provider is more suitable for those who want to create an identity provider rather than connect to one.
openid-client is a server side OpenID Relying Party (RP, Client) implementation for Node.js runtime, supports passport.
WARNING: Node.js 12 or higher is required for openid-client@3 and above. For older Node.js versions use openid-client@2.
The following client/RP features from OpenID Connect/OAuth2.0 specifications are implemented by openid-client.
Filip Skokan has certified that openid-client
conforms to the RP Basic, RP Implicit, RP Hybrid, RP Config, RP Dynamic and RP Form Post profiles
of the OpenID Connect™ protocol.
If you want to quickly add OpenID Connect authentication to Node.js apps, feel free to check out Auth0's Node.js SDK and free plan at auth0.com/overview.
If you or your business use openid-client, please consider becoming a Patron so I can continue maintaining it and adding new features carefree. You may also donate one-time via PayPal.
The library exposes what are essentially steps necessary to be done by a relying party consuming OpenID Connect Authorization Server responses or wrappers around requests to its endpoints. Aside from a generic OpenID Connect passport strategy it does not expose neither express or koa middlewares. Those can however be built using the exposed API.
Discover an Issuer configuration using its published .well-known endpoints
const { Issuer } = require('openid-client');
Issuer.discover('https://accounts.google.com') // => Promise
.then(function (googleIssuer) {
console.log('Discovered issuer %s %O', googleIssuer.issuer, googleIssuer.metadata);
});
Authorization Code flow is for obtaining Access Tokens (and optionally Refresh Tokens) to use with
third party APIs securely as well as Refresh Tokens. In this quick start your application also uses
PKCE instead of state
parameter for CSRF protection.
Create a Client instance for that issuer's authorization server intended for Authorization Code flow.
See the documentation for full API details.
const client = new googleIssuer.Client({
client_id: 'zELcpfANLqY7Oqas',
client_secret: 'TQV5U29k1gHibH5bx1layBo0OSAvAbRT3UYW3EWrSYBB5swxjVfWUa1BS8lqzxG/0v9wruMcrGadany3',
redirect_uris: ['http://localhost:3000/cb'],
response_types: ['code'],
// id_token_signed_response_alg (default "RS256")
// token_endpoint_auth_method (default "client_secret_basic")
}); // => Client
When you want to have your end-users authorize you need to send them to the issuer'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.
const { generators } = require('openid-client');
const code_verifier = generators.codeVerifier();
// store the code_verifier in your framework's session mechanism, if it is a cookie based solution
// it should be httpOnly (not readable by javascript) and encrypted.
const code_challenge = generators.codeChallenge(verifier);
client.authorizationUrl({
scope: 'openid email profile',
resource: 'https://my.api.example.com/resource/32178',
code_challenge,
code_challenge_method: 'S256',
});
When end-users are redirected back to your redirect_uri
your application consumes the callback and
passes in the code_verifier
to include it in the authorization code grant token exchange.
const params = client.callbackParams(req);
client.callback('https://client.example.com/callback', params, { code_verifier }) // => Promise
.then(function (tokenSet) {
console.log('received and validated tokens %j', tokenSet);
console.log('validated ID Token claims %j', tokenSet.claims());
});
You can then call the userinfo_endpoint
.
client.userinfo(access_token) // => Promise
.then(function (userinfo) {
console.log('userinfo %j', userinfo);
});
And later refresh the tokenSet if it had a refresh_token
.
client.refresh(refresh_token) // => Promise
.then(function (tokenSet) {
console.log('refreshed and validated tokens %j', tokenSet);
console.log('refreshed ID Token claims %j', tokenSet.claims());
});
Implicit response_type=id_token
flow is perfect for simply authenticating your end-users, assuming
the only job you want done is authenticating the user and then relying on your own session mechanism
with no need for accessing any third party APIs with an Access Token from the Authorization Server.
Create a Client instance for that issuer's authorization server intended for ID Token implicit flow.
See the documentation for full API details.
const client = new googleIssuer.Client({
client_id: 'zELcpfANLqY7Oqas',
redirect_uris: ['http://localhost:3000/cb'],
response_types: ['id_token'],
// id_token_signed_response_alg (default "RS256")
}); // => Client
When you want to have your end-users authorize you need to send them to the issuer'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.
const { generators } = require('openid-client');
const nonce = generators.nonce();
// store the nonce in your framework's session mechanism, if it is a cookie based solution
// it should be httpOnly (not readable by javascript) and encrypted.
client.authorizationUrl({
scope: 'openid email profile',
response_mode: 'form_post',
nonce,
});
When end-users hit back your redirect_uri
with a POST (authorization request included form_post
response mode) your application consumes the callback and passes the nonce
in to include it in the
ID Token verification steps.
// assumes req.body is populated from your web framework's body parser
const params = client.callbackParams(req);
client.callback('https://client.example.com/callback', params, { nonce }) // => Promise
.then(function (tokenSet) {
console.log('received and validated tokens %j', tokenSet);
console.log('validated ID Token claims %j', tokenSet.claims());
});
Yes. Everything that's documented is subject to Semantic Versioning 2.0.0. The rest is to be considered private API and is subject to change between any versions.
It is only built for Node.js environment.
Use openid-client@2 release line, but be sure to check its documentation as there were breaking changes between versions 2 and 3.
FAQs
OpenID Connect Relying Party (RP, Client) implementation for Node.js runtime, supports passportjs
The npm package openid-client receives a total of 1,938,603 weekly downloads. As such, openid-client popularity was classified as popular.
We found that openid-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.