Skip to content

jbucknor/simple-oauth2

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple OAuth2

NPM Package Version Build Status Dependency Status

Node.js client library for OAuth2. OAuth2 allows users to grant access to restricted resources by third party applications.

Table of Contents

Requirements

The node client library is tested against Node 8 LTS and newer versions. Older node versions are unsupported.

Usage

Install the client library using npm:

npm install --save simple-oauth2

Create a new instance by specifying the minimal configuration

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

const oauth2 = require('simple-oauth2').create(credentials);

OAuth2 Supported grants

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

Authorization Code

The Authorization Code grant type is made up from two parts. At first your application asks to the user the permission to access their data. If the user approves the OAuth2 server sends to the client an authorization code. In the second part, the client POST the authorization code along with its client secret to the oauth server in order to get the access token.

async function run() {
  const oauth2 = require('simple-oauth2').create(credentials);

  const authorizationUri = oauth2.authorizationCode.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 tokenConfig = {
    code: '<code>',
    redirect_uri: 'http://localhost:3000/callback',
    scope: '<scope>',
  };

  try {
    const result = await oauth2.authorizationCode.getToken(tokenConfig);
    const accessToken = oauth2.accessToken.create(result);
  } catch (error) {
    console.log('Access Token Error', error.message);
  }
}

run();

Password Credentials Flow

The Password Owner grant type is suitable when the resource owner has a trust relationship with the client, such as its computer operating system or a highly privileged application. Use this flow only when other flows are not viable or when you need a fast way to test your application.

async function run() {
  const oauth2 = require('simple-oauth2').create(credentials);

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

  try {
    const result = await oauth2.ownerPassword.getToken(tokenConfig);
    const accessToken = oauth2.accessToken.create(result);
  } catch (error) {
    console.log('Access Token Error', error.message);
  }
}

run();

Client Credentials Flow

The Client Credentials grant type is suitable when client is requesting access to the protected resources under its control.

async function run() {
  const oauth2 = require('simple-oauth2').create(credentials);

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

  try {
    const result = await oauth2.clientCredentials.getToken(tokenConfig);
    const accessToken = oauth2.accessToken.create(result);
  } catch (error) {
    console.log('Access Token error', error.message);
  }
}

run();

Access Token object

When a token expires we need to refresh it. Simple OAuth2 offers the AccessToken class that add a couple of useful methods to refresh the access token when it is expired.

async function run() {
  const tokenObject = {
    'access_token': '<access-token>',
    'refresh_token': '<refresh-token>',
    'expires_in': '7200'
  };

  let accessToken = oauth2.accessToken.create(tokenObject);

  if (accessToken.expired()) {
    try {
      const params = {
        scope: '<scope>',
      };

      accessToken = await accessToken.refresh(params);
    } 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 (token.expired(EXPIRATION_WINDOW_IN_SECONDS)) {
    try {
      accessToken = await accessToken.refresh();
    } catch (error) {
      console.log('Error refreshing access token: ', error.message);
    }
  }
}

run();

When you've done with the token or you want to log out, you can revoke the 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() {
  // Revoke both access and refresh tokens
  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();

Errors

Errors are returned when a 4xx or 5xx status code is received.

BoomError

As a standard boom error you can access any of the boom error properties. The total amount of information varies according to the generated status code.

async function run() {
  try {
    await oauth2.authorizationCode.getToken();
  } catch(error) {
    console.log(error);
  }
}

run();
// => {
//     "statusCode": 401,
//     "error": "Unauthorized",
//     "message": "invalid password"
// }

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*

API

For a complete reference, see the module API.

Usage examples

For complete reference examples, see the example folder.

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.

About

A simple Node.js client library for Oauth2

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%