npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

oauth-v2-client

v1.2.3

Published

Oauth V2 client based on axios

Downloads

232

Readme

Oauth v2 Client

Version Downloads/week License

Oauth 2.0 client for node.js, based on Axios.

This package covers access to tokens, renewal of tokens, and injection of the token in Axios request config

Installation

npm install oauth-v2-client

Usage

Here is how we create an instance of the module for your API.

import OauthClient from "oauth-v2-client";

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    callbackUrl: "http://my-app.example.com/callback",
    accessTokenUrl: "https://example.com/oauth2/access_token",
    authUrl: "https://example.com/oauth2/authorize",
    apiBaseURL: "https://api.example.com",
  }
});

The options used in the example above are optional for the most part, and are only part of the available options, which we will list in the next section.

Global Options

The object used to initialize the module has two properties:

  • oauthOptions: for oauth options (required)
  • requestOptions: global request options (optional)
    • query: global URL query parameters
    • headers: global headers
    • body: global body
    • bodyType: json | x-www-form-urlencoded

oauthOptions properties

| Property | Type | Required | Default | Description | | ------------------- | ------ | -------- | -------------------------------- | ------------------------------------------------------------ | | callbackUrl | string | false | | The callback URL should match the one you use during the application registration process. | | authUrl | string | true | | The endpoint for authorization server. This is used to get the authorization code. | | accessTokenUrl | string | false | | The endpoint for authentication server. This is used to exchange the authorization code for an access token. | | clientId | string | true | | The client identifier issued to the client during the application registration process. | | clientSecret | string | false | | The client secret issued to the client during the application registration process. | | scopes | array | false | | The scopes of the access request. | | state | string | false | generated when needed if missing | An opaque value that is used for preventing cross-site request forgery | | username | string | false | | username for Password Grant | | password | string | false | | password for Password Grant | | codeChallengeMethod | string | false | S256 | Algorithm used for generating the Code Challenge | | codeVerifier | string | false | generated when needed if missing | A random, 43-128 character string used to connect the authorization request to the token request. RFC spec | | basicAuthHeader | string | false | | Send credentials as basic authentication header | | apiBaseURL | string | false | | Your api base url | | jwtToken | string | false | | JWT token for jwt grant |

Grants

Implicit Grant

The implicit grant is a simplified authorization code flow optimized for clients implemented in a browser using a scripting language such as JavaScript. In the implicit flow, instead of issuing the client an authorization code, the client is issued an access token directly.

Get redirect uri

api.implicit.getAuthUri()

Extract token

api.implicit.getToken(callback)

Full Example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    callbackUrl: "http://localhost:3000/callback",
    accessTokenUrl: "https://example.com/oauth/token",
    authUrl: "https://example.com/oauth/authorize"
  }
});

// redirect to provider authentication page
app.get("/oauth/implicit", function (req, res) {
  res.redirect(api.implicit.getAuthUri());
});

// extract token in the callback
app.get("/callback", function (req, res) {
  res.json(api.implicit.getToken(req.originalUrl));
});

httpServer.listen(3000);

Authorization Code Grant

The authorization code grant type is used to obtain both access tokens and refresh tokens and is optimized for confidential clients. Since this is a redirection-based flow, the client must be capable of interacting with the resource owner's user-agent (typically a web browser) and capable of receiving incoming requests (via redirection) from the authorization server.

Get redirect uri

api.authorizationCode.getAuthUri()

Get token

api.authorizationCode.getToken({
    callbackUrl: callback,
    onSuccess: (data) => {
		// code here
    },
    onError: (error) => {
     	// handle error here
    },
  });

Full Example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    callbackUrl: "http://localhost:3000/callback",
    accessTokenUrl: "https://example.com/oauth/token",
    authUrl: "https://example.com/oauth/authorize"
  }
});

// redirect to provider authentication page
app.get("/oauth/auth-code", function (req, res) {
  res.redirect(api.authorizationCode.getAuthUri());
});

// extract code in the callback add request the token
app.get("/callback", async function (req, res) {
    await api.authorizationCode.getToken({
        callbackUrl: req.originalUrl,
        onSuccess: (data) => {
          	return res.status(200).json(data);
        },
        onError: (error) => {
          	return res.status(500).json(error.response?.data);
        },
    });
});

httpServer.listen(3000);

Authorization Code PKCE Grant

OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack.

PKCE (RFC 7636) is an extension to the authorization code flow to prevent several attacks and to be able to securely perform the OAuth exchange from public clients.

Get redirect uri

api.authorizationCodePKCE.getAuthUri()

Get token

api.authorizationCodePKCE.getToken({
    callbackUrl: callback,
    onSuccess: (data) => {
		// code here
    },
    onError: (error) => {
     	// handle error here
    },
});

Full Example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    callbackUrl: "http://localhost:3000/callback",
    accessTokenUrl: "https://example.com/oauth/token",
    authUrl: "https://example.com/oauth/authorize"
  }
});

// redirect to provider authentication page
app.get("/oauth/auth-code-pkce", function (req, res) {
  res.redirect(api.authorizationCodePKCE.getAuthUri());
});

// extract code in the callback add request the token
app.get("/callback", async function (req, res) {
    await api.authorizationCodePKCE.getToken({
        callbackUrl: req.originalUrl,
        onSuccess: (data) => {
          	return res.status(200).json(data);
        },
        onError: (error) => {
          	return res.status(500).json(error.response?.data);
        },
    });
});

httpServer.listen(3000);

Password Grant

The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token. The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).

Get token method

await api.password.getToken({
    username: req.body.username,
    password: req.body.password,
    onSuccess: (data) => {
		// code here
    },
    onError: (error) => {
		// handle error
    },
});

Full example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import { json } from "body-parser";
import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    accessTokenUrl: "https://example.com/oauth/token"
  }
});

app.post("/oauth/password", [
  json(),
  async function (req: any, res: any) {
    try {
        // get the the token from credentials
      await api.password.getToken({
        username: req.body.username,
        password: req.body.password,
        onSuccess: (data) => {
          return res.status(200).json(api.password.token);
        },
        onError: (error) => {
          return res.status(500).json(error.response?.data);
        },
      });
    } catch (error) {
      return res.status(500).json(error.message);
    }
  },
]);

httpServer.listen(3000);

Client Credentials Grant

The client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client, or to protected resources previously arranged with the authorization server. Client credentials are used as an authorization grant typically when the client is acting on its own behalf (the client is also the resource owner) or is requesting access to protected resources based on an authorization previously arranged with the authorization server.

Get token method

await api.client.getToken({
    onSuccess: (data) => {
		// code here
    },
    onError: (error) => {
		// handle error
	},
});

Full example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import { json } from "body-parser";
import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
  oauthOptions: {
    clientId: "client_id_value",
    clientSecret: "client_secret_value",
    accessTokenUrl: "https://example.com/oauth/token"
  }
});

app.post("/oauth/client", [
  json(),
  async function (req: any, res: any) {
    await api.client.getToken({
      onSuccess: (data) => {
        return res.status(200).json(data);
      },
      onError: (error) => {
        return res.status(500).json(error.response?.data);
      },
    });
  },
]);

httpServer.listen(3000);

JWT Grant

JWT Bearer Token is for client authentication. To use a Bearer JWT as an authorization grant, the client uses an access token request as defined in Section 4 of the OAuth Assertion Framework [RFC7521] with the following specific parameter values and encodings.

Get token method

await api.jwt.getToken({
    onSuccess: (data) => {
		// code here
    },
    onError: (error) => {
		// handle error
	},
});

Full example (Node.js + Typescript)

Dependencies: body-parser, express, oauth-v2-client

import { json } from "body-parser";
import express from "express";
import http from "http";
import OauthClient from "oauth-v2-client";

const app = express();
const httpServer = http.createServer(app);

const api = new OauthClient({
    oauthOptions: {
        clientId: "client_id_value",
        clientSecret: "client_secret_value",
        accessTokenUrl: "https://example.com/oauth/token",
        jwtToken: "easdqd---- A JWT TOKEN -----jmlu"
    }
});

app.post("/oauth/jwt", [
    json(),
    async function (req: any, res: any) {
        await api.jwt.getToken({
            grant_type: "urn:example-provider:oauth2:jwt", // just an example
            onSuccess: (data) => {
                return res.status(200).json(data);
            },
            onError: (error) => {
                return res.status(500).json(error.response?.data);
                                            },
        });
    },
]);

httpServer.listen(3000);

Sign

Sign API requests

For all grants, there is a method call sign which help to sign Axios requests.

Sign method takes an object as a unique parameter which has all AxiosRequestConfig properties, and those 2 additional properties:

  • proxy: Use Proxy-Authorization instead of Authorization
  • token: Token object with the following properties: access_token, token_type.

Example with authorization code (Node.Js + Typescript)

// get the saved token
const token = {};

// using http helper (get, post, put etc)
await Axios.get("/2.0/user/emails", api.authorizationCode.sign({
  token
})).then((response) => {
      return res.status(200).json(response.data);
}).catch((error) => {
      return res.status(500).json(error);
});

// using custom request
await Axios.request(api.authorizationCode.sign({
    token,
    method: "get",
    url: "/2.0/user/emails"
})).then((response) => {
      return res.status(200).json(response.data);
}).catch((error) => {
      return res.status(500).json(error);
});

Licence

Apache M.I.T