Socket
Socket
Sign inDemoInstall

simple-oauth2

Package Overview
Dependencies
11
Maintainers
2
Versions
51
Alerts
File Explorer

Advanced tools

Install Socket

Protect your apps from supply chain attacks

Install

simple-oauth2

Node.js client for OAuth2

    5.0.0latest
    GitHub
    npm

Version published
Maintainers
2
Weekly downloads
184,838
increased by8.05%

Weekly downloads

Changelog

Source

5.0.0

New features

  • #332 Preserve query params on authorizePath on authorizeURL method

Maintainance

  • #341 Rewrite integration tests
  • #382 Update eslint parser dependencies
  • #390 Add Node 16 to test matrix
  • #404 Update ava to v4.x
  • #405 Update @hapi/hoek to v10.0.0
  • #406 Update @hapi/wreck to v18.0.0
  • #407 Update @hapi/boom to v10.0.0
  • #407 Update doctoc to v2.x
  • #408 Add Node 18 to test matrix

Documentation

  • #403 Add LinkedIn example

Breaking changes

  • 340 Accept only options available per grant type
  • #403 Drop support for Node 12. Require at least Node 14
  • #406 Disable redirects by default

Readme

Source

Simple OAuth2

NPM Package Version Build Status Dependency Status

Simple OAuth2 is a Node.js client library for the OAuth 2.0 authorization framework. OAuth 2.0 is the industry-standard protocol for authorization, enabling third-party applications to obtain limited access to an HTTP service, either on behalf of a resource owner or by allowing the third-party application to obtain access on its own behalf.

Table of Contents

Requirements

VersionNode support
5.xNode 14.x or higher
6.x (Development)Node 16.x or higher

Older node versions are unsupported.

Usage

Install the client library using npm:

npm install --save simple-oauth2

With a minimal configuration, create a client instance of any supported grant type.

const config = {
  client: {
    id: '<client-id>',
    secret: '<client-secret>'
  },
  auth: {
    tokenHost: 'https://api.oauth.com'
  }
};

const { ClientCredentials, ResourceOwnerPassword, AuthorizationCode } = require('simple-oauth2');

For a complete reference of configuration options, see the API Options

Supported Grant Types

Depending on your use-case, any of the following supported grant types may be useful:

Authorization Code Grant

The Authorization Code grant type is used by confidential and public clients to exchange an authorization code for an access token. After the user returns to the client via the redirect URL, the application will get the authorization code from the URL and use it to request an access token.

async function run() {
  const client = new AuthorizationCode(config);

  const authorizationUri = client.authorizeURL({
    redirect_uri: 'http://localhost:3000/callback',
    scope: '<scope>',
    state: '<state>'
  });

  // Redirect example using Express (see http://expressjs.com/api.html#res.redirect)
  res.redirect(authorizationUri);

  const tokenParams = {
    code: '<code>',
    redirect_uri: 'http://localhost:3000/callback',
    scope: '<scope>',
  };

  try {
    const accessToken = await client.getToken(tokenParams);
  } catch (error) {
    console.log('Access Token Error', error.message);
  }
}

run();

See the API reference for a complete reference of available options or any of our available examples at the example folder.

Resource Owner Password Credentials Grant

The Resource Owner Password Credentials grant type is a way to exchange a user's credentials for an access token. Because the client application has to collect the user's password and send it to the authorization server, it is not recommended that this grant be used at all anymore.

async function run() {
  const client = new ResourceOwnerPassword(config);

  const tokenParams = {
    username: 'username',
    password: 'password',
    scope: '<scope>',
  };

  try {
    const accessToken = await client.getToken(tokenParams);
  } catch (error) {
    console.log('Access Token Error', error.message);
  }
}

run();

See the API reference for a complete reference of available options.

Client Credentials Grant

The Client Credentials grant type is used by clients to obtain an access token outside of the context of a user. This is typically used by clients to access resources about themselves rather than to access a user's resources.

async function run() {
  const client = new ClientCredentials(config);

  const tokenParams = {
    scope: '<scope>',
  };

  try {
    const accessToken = await client.getToken(tokenParams);
  } catch (error) {
    console.log('Access Token error', error.message);
  }
}

run();

See the API reference for a complete reference of available options.

Access Token

On completion of any supported grant type an access token will be obtained. A list of supported operations can be found below.

Refresh an access token

On long lived applications, it is often necessary to refresh access tokens. In such scenarios the access token is usually persisted in an external database by first serializing it.

async function run() {
  const accessTokenJSONString = JSON.stringify(accessToken);

  await persistAccessTokenJSON(accessTokenJSONString);
}

run();

By the time we need to refresh the persistent access token, we can get back an AccessToken instance by using the client's .createToken method.

async function run() {
  const accessTokenJSONString = await getPersistedAccessTokenJSON();

  let accessToken = client.createToken(JSON.parse(accessTokenJSONString));
}

run();

Once we have determined the access token needs refreshing with the .expired() method, we can finally refresh it with a .refresh() method call.

async function run() {
  if (accessToken.expired()) {
    try {
      const refreshParams = {
        scope: '<scope>',
      };

      accessToken = await accessToken.refresh(refreshParams);
    } catch (error) {
      console.log('Error refreshing access token: ', error.message);
    }
  }
}

run();

The .expired() helper is useful for knowing when a token has definitively expired. However, there is a common race condition when tokens are near expiring. If an OAuth 2.0 token is issued with a expires_in property (as opposed to an expires_at property), there can be discrepancies between the time the OAuth 2.0 server issues the access token and when it is received.

These come down to factors such as network and processing latency and can be worked around by preemptively refreshing the access token:

async function run() {
  const EXPIRATION_WINDOW_IN_SECONDS = 300; // Window of time before the actual expiration to refresh the token

  if (accessToken.expired(EXPIRATION_WINDOW_IN_SECONDS)) {
    try {
      accessToken = await accessToken.refresh();
    } catch (error) {
      console.log('Error refreshing access token: ', error.message);
    }
  }
}

run();

Warning: Tokens obtained with the Client Credentials grant may not be refreshed. Fetch a new token when it's expired.

See the API reference for a complete reference of available options.

Revoke an access or refresh token

When you've done with the token or you want to log out, you can revoke both access and refresh tokens.

async function run() {
  try {
    await accessToken.revoke('access_token');
    await accessToken.revoke('refresh_token');
  } catch (error) {
    console.log('Error revoking token: ', error.message);
  }
}

run();

As a convenience method, you can also revoke both tokens in a single call:

async function run() {
  try {
    // Revokes both tokens, refresh token is only revoked if the access_token is properly revoked
    await accessToken.revokeAll();
  } catch (error) {
    console.log('Error revoking token: ', error.message);
  }
}

run();

See the API reference for a complete reference of available options.

Errors

Whenever a client or server error is produced, a boom error is thrown by the library. As such any boom error property is available, but the exact information may vary according to the type of error.

async function run() {
  const client = new ClientCredentials(config);

  try {
    await client.getToken();
  } catch(error) {
    console.log(error.output);
  }
}

run();

// { statusCode: 401,
//   payload:
//    { statusCode: 401,
//      error: 'Unauthorized',
//      message: 'Response Error: 401 Unauthorized' },
//   headers: {} }

Debugging the module

This module uses the debug module to help on error diagnosis. Use the following environment variable to help in your debug journey:

DEBUG=*simple-oauth2*

Contributing

See CONTRIBUTING

Authors

Andrea Reginato

Contributors

Special thanks to the following people for submitting patches.

Changelog

See CHANGELOG

License

Simple OAuth 2.0 is licensed under the Apache License, Version 2.0

Thanks to Open Source

Simple OAuth 2.0 come to life thanks to the work I've made in Lelylan, an open source microservices architecture for the Internet of Things. If this project helped you in any way, think about giving us a star on Github.

Keywords

FAQs

Last updated on 23 Oct 2022

Did you know?

Socket installs a GitHub app to automatically flag issues on every pull request and report the health of your dependencies. Find out what is inside your node modules and prevent malicious activity before you update the 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