Socket
Socket
Sign inDemoInstall

openid-client

Package Overview
Dependencies
35
Maintainers
1
Versions
180
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    openid-client

OpenID Connect Relying Party (RP, Client) implementation for Node.js


Version published
Maintainers
1
Created

Package description

What is openid-client?

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.

What are openid-client's main functionalities?

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);
})();

Other packages similar to openid-client

Readme

Source

openid-client

build dependencies codecov npm licence

openid-client is a server side OpenID Relying Party (RP, Client) implementation for Node.js

Table of Contents

Implemented specs & features

The following client/RP features from OpenID Connect/OAuth2.0 specifications are implemented by openid-client.

Example

Head over to the example folder to see the library in use. This example is deployed and configured to use an example OpenID Connect Provider here. The provider is using oidc-provider library.

Get started

On the off-chance you want to manage multiple clients for multiple issuers you need to first get an Issuer instance.

const Issuer = require('openid-client').Issuer;
Issuer.discover('https://accounts.google.com') // => Promise
  .then(function (googleIssuer) {
    console.log('Discovered issuer %s', googleIssuer);
  });

manually

const Issuer = require('openid-client').Issuer;
const googleIssuer = new Issuer({
  issuer: 'https://accounts.google.com',
  authorization_endpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
  token_endpoint: 'https://www.googleapis.com/oauth2/v4/token',
  userinfo_endpoint: 'https://www.googleapis.com/oauth2/v3/userinfo',
  jwks_uri: 'https://www.googleapis.com/oauth2/v3/certs',
}); // => Issuer
console.log('Set up issuer %s', googleIssuer);

Now you can create your Client.

You should provide the following metadata; client_id, client_secret. You can also provide id_token_signed_response_alg (defaults to RS256) and token_endpoint_auth_method (defaults to client_secret_basic);

const client = new googleIssuer.Client({
  client_id: 'zELcpfANLqY7Oqas',
  client_secret: 'TQV5U29k1gHibH5bx1layBo0OSAvAbRT3UYW3EWrSYBB5swxjVfWUa1BS8lqzxG/0v9wruMcrGadany3'
}); // => Client

via registration client uri

Should your oidc provider have provided you with a registration client uri and registration access token you can also have the Client discovered.

new googleIssuer.Client.fromUri(registration_client_uri, registration_access_token) // => Promise
  .then(function (client) {
    console.log('Discovered client %s', client);
  });

Usage

Getting authorization url

client.authorizationUrl({
  redirect_uri: 'https://client.example.com/callback',
  scope: 'openid email',
}); // => String

Processing callback

client.authorizationCallback('https://client.example.com/callback', request.query) // => Promise
  .then(function (tokenSet) {
    console.log('received tokens %j', tokenSet);
  });

Processing callback with state or nonce check

const state = session.state;
const nonce = session.nonce;

client.authorizationCallback('https://client.example.com/callback', request.query, { state, nonce }) // => Promise
  .then(function (tokenSet) {
    console.log('received tokens %j', tokenSet);
  });

Refreshing a token

client.refresh(refreshToken) // => Promise
  .then(function (tokenSet) {
    console.log('refreshed tokens %j', tokenSet);
  });

Tip: accepts TokenSet as well as direct refresh token values;

Revoke a token

client.revoke(token) // => Promise
  .then(function (response) {
    console.log('revoked token %s', token, response);
  });

Introspect a token

client.introspect(token) // => Promise
  .then(function (response) {
    console.log('token details %j', response);
  });

Fetching userinfo

client.userinfo(accessToken) // => Promise
  .then(function (userinfo) {
    console.log('userinfo %j', userinfo);
  });

Tip: accepts TokenSet as well as direct access token values;

via POST

client.userinfo(accessToken, { verb: 'post' }); // => Promise

auth via query

client.userinfo(accessToken, { via: 'query' }); // => Promise

auth via body

client.userinfo(accessToken, { verb: 'post', via: 'body' }); // => Promise

userinfo also handles (as long as you have the proper metadata configured) responses that are:

  • signed
  • signed and encrypted (nested JWT)
  • just encrypted

Fetching Distributed Claims

let claims = {
  sub: 'userID',
  _claim_names: {
    credit_history: 'src1',
    email: 'src2',
  },
  _claim_sources: {
    src1: { endpoint: 'https://src1.example.com/claims', access_token: 'foobar' },
    src2: { endpoint: 'https://src2.example.com/claims' },
  },
};

client.fetchDistributedClaims(claims, { src2: 'bearer.for.src2' }) // => Promise
  .then(function (output) {
    console.log('claims %j', claims); // ! also modifies original input, does not create a copy
    console.log('output %j', output);
    // removes fetched names and sources and removes _claim_names and _claim_sources members if they
    // are empty
  });
  // when rejected the error will have a property 'src' with the source name it relates to

Unpacking Aggregated Claims

let claims = {
  sub: 'userID',
  _claim_names: {
    credit_history: 'src1',
    email: 'src2',
  },
  _claim_sources: {
    src1: { JWT: 'probably.a.jwt' },
    src2: { JWT: 'probably.another.jwt' },
  },
};

client.unpackAggregatedClaims(claims) // => Promise, autodiscovers JWT issuers, verifies signatures
  .then(function (output) {
    console.log('claims %j', claims); // ! also modifies original input, does not create a copy
    console.log('output %j', output);
    // removes fetched names and sources and removes _claim_names and _claim_sources members if they
    // are empty
  });
  // when rejected the error will have a property 'src' with the source name it relates to

Custom token endpoint grants

Use when the token endpoint also supports client_credentials or password grants;

client.grant({
  grant_type: 'client_credentials'
}); // => Promise

client.grant({
  grant_type: 'password',
  username: 'johndoe',
  password: 'A3ddj3w',
}); // => Promise

Registering new client (via Dynamic Registration)

issuer.Client.register(metadata, [keystore]) // => Promise
  .then(function (client) {
    console.log('Registered client %s, %j', client, client.metadata);
  });

Configuration

Changing HTTP request defaults

Setting defaultHttpOptions on Issuer always merges your passed options with the default. openid-client uses got for http requests with the following default request options

const DEFAULT_HTTP_OPTIONS = {
  followRedirect: false,
  headers: { 'User-Agent': `${pkg.name}/${pkg.version} (${pkg.homepage})` },
  retries: 0,
  timeout: 1500,
};

You can add your own headers, change the user-agent used or change the timeout setting

Issuer.defaultHttpOptions = { timeout: 2500, headers: { 'X-Your-Header': '<whatever>' } };

Confirm your httpOptions by

console.log('httpOptions %j', Issuer.defaultHttpOptions);

Keywords

FAQs

Last updated on 10 Sep 2016

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc