How-to

OAuth2 authentication for GraphQL in Node.js

The OAuth 2.0 protocol, the current standard for managing user access to websites or application resources, provides client credential flow for modern APIs. This protocol allows resource owners to grant access to protected resources by issuing clients access tokens.

Photo by Propel Data

OAuth login box

The OAuth 2.0 protocol, the current standard for managing user access to websites or application resources, provides client credential flow for modern APIs. This protocol allows resource owners to grant access to protected resources by issuing clients access tokens.

OAuth 2.0, which improves on the previous OAuth 1.0 and 1.1 standards, offers a robust means of authorizing third-party applications per the consent of resource-owning users.

Though it’s often used with REST APIs, OAuth 2.0 is not limited to REST APIs. It’s possible to layer authorization on top of GraphQL using OAuth 2.0 to provide scoped, protected access to GraphQL clients for user resources.

In this article, you’ll learn how to implement the OAuth 2.0 client credentials flow with GraphQL using Node.js.

Why do APIs use OAuth 2.0 Authentication?

OAuth 2.0 is the latest version of the framework designed as a universal standard for web API-driven authorization. It’s used by large companies like Twitter, Facebook, and GitHub, and any third-party application can use it to secure data.

OAuth 2.0 authentication offers multiple advantages for API clients and users. The OAuth 2.0 standard eliminates the need for third-party sites to store and manage passwords and in so doing, reduces the risk of password leaks or attacks. OAuth 2.0 also transfers the burden of credential management to providers that are well equipped to securely manage user data at scale.

The protocol is simple for developers to implement, since only the authorization server and client are involved and no additional credential generation is required. Authorization with OAuth 2.0 is also scoped, limiting third-party access to user information.

Integrating OAuth 2.0 into a GraphQL application involves managing a few different authorization artifacts vital to the authorization process. These include the client ID, client secret, and access token.

A client ID uniquely identifies third-party applications; it’s public and unique across all OAuth clients to provide immunity to phishing. The client secret is a credential known only to the authorization server and a third-party application. The access token — issued by the authorization server after it receives a valid client ID and secret — authorizes a third-party application.

Note: You must ensure that your client secret never leaks into a public application and that your access token is kept confidential at all times, in transit and in storage.

The diagram below demonstrates the flow for this tutorial:

You’ll be authenticating using OAuth 2.0 against Propel Data, an analytics platform that helps developers build data apps at scale using a feature-rich GraphQL API.

Integrating the OAuth 2.0 Client Credentials Flow

To demonstrate the credentials flow shown above, you will write a simple script that acquires an access token from Propel’s authorization server and retrieves a list of data sources from the service’s GraphQL API.

First, you’ll create an Application with Propel. The process should be fairly intuitive: sign in to the Propel Console and create a new Application. You’ll be issued a unique client ID-secret pair consisting of two artifacts you’ll later exchange for an access token.

Once you’ve registered your Application with Propel, you can start coding the Propel client. The structure for this is below:

propel-oauth2
├── src
│   └── propel.mjs
├── .env
├── .gitignore
├── index.mjs
├── package-lock.json
└── package.json

To bootstrap the Application and produce the above structure, type the following in a console of your choosing:

$ mkdir propel-oauth2
$ cd propel-oauth2
$ mkdir src
$ touch index.mjs .env .gitignore src/propel.mjs

For this tutorial, you’ll need to install the cross-fetch and dotenv libraries using either npm or yarn. The former provides a cross-platform (Node, browser, and mobile) fetch API, while the latter is a neat package that appends arbitrary configuration in a .env file to a list of globally accessible environment data.

Type the following in your console to install these packages:

$ npm install cross-fetch dotenv

Start the coding process by placing the Propel client ID and secret in the .env file.

PROPEL_CLIENT_ID=propel-client-id-goes-here
PROPEL_CLIENT_SECRET=propel-client-secret-goes-here

Since these artifacts are sensitive, you must exempt them from version control tracking so that they’re not exposed. Simply add a .env entry to the .gitignore file, also in the project’s root:

.env

With that change made, we’re ready to fetch the OAuth 2.0 access token from Propel’s API.

Fetching an OAuth 2.0 Access Token

Next, in the propel.mjs file, you will write two functions — fetchPropelAccessToken and fetchPropelMetrics — that retrieve, respectively, a Propel access token and metrics for your Propel account. Let’s start by defining fetchPropelAccessToken.

import fetch from 'cross-fetch'

export async function fetchPropelAccessToken (clientId, clientSecret) {
  const response = await fetch(
    'https://auth.us-east-2.propeldata.com/oauth2/token',
    {
      method: 'POST',
      body: new URLSearchParams({
        grant_type: 'client_credentials',
        client_id: clientId,
        client_secret: clientSecret
      })
    }
  )

  const data = await response.json()

  if ('error' in data) {
    throw new Error(data.error)
  }

  return data.access_token
}

The access token that you request from Propel’s authorization server will make an HTTP request to Propel’s authorization server with the client ID and secret in order to obtain an access token.

The access token that you request from Propel’s authorization server will be returned in a JSON response object and is valid for one hour. Using an access token is a prerequisite for fetching any additional data from Propel’s resource server, such as a list of data sources.

Using an OAuth 2.0 Access Token

Next, let’s use the access token. As with the previous function, fetchPropelMetrics makes an HTTP request. But fetchPropelMetrics doesn’t make an HTTP request to the access token server; instead, it makes a request to Propel’s GraphQL API — or the “resource server” in OAuth 2.0 terminology — and includes the access token inside the Authorization header.

export async function fetchPropelMetrics (token, count) {
  const response = await fetch(
    'https://api.us-east-2.propeldata.com/graphql',
    {
      method: 'POST',
      headers: {
        authorization: `Bearer ${token}`,
        'content-type': 'application/json'
      },
      body: JSON.stringify({
        query: `query { metrics (first: ${count}) { nodes { id } } }`
      })
    }
  )

  return await response.json()
}

Finally, you put each of the above artifacts together into a single entry script named index.mjs defined in the root of the project. In this file, you will call the fetchPropelAccessToken and fetchPropelMetrics functions. First, we will call fetchPropelAccessToken to retrieve an access token. Then, we will pass this access token to fetchPropelMetrics. Propel’s GraphQL API will check our access token and, if we are authorized, will return us a list of metric IDs.

import * as dotenv from 'dotenv'
dotenv.config()

import { fetchPropelAccessToken, fetchPropelMetrics } from './src/propel.mjs'

const token = await fetchPropelAccessToken(
  process.env.PROPEL_CLIENT_ID,
  process.env.PROPEL_CLIENT_SECRET
)

const metrics = await fetchPropelMetrics(token, 2)

console.log(JSON.stringify(metrics))

The access token issued by the Propel authorization server is temporary, which might be a problem for long-running processes like application servers and daemons. If you intend to implement this credentials flow and resource access in a long-running application that might require repeat calls to the Propel authorization server, you should consider implementing an adjacent mechanism for managing the expiration and reissuing of tokens.

Conclusion: Authenticating GraphQL in Node.js with OAuth 2.0

OAuth 2.0, the secure framework for granting account access to third-party applications, enables smooth authorization for users and secure resource access for developers. Though OAuth 2.0 is often used in REST APIs, as you saw in this tutorial, it’s possible to extend its capabilities to GraphQL servers.

You can authenticate a GraphQL API using OAuth 2.0 using Node.js in just a few steps with Propel Data. Propel’s serverless GraphQL API platform provides in-product analytics for customer-facing web and mobile applications. Use it to build projects quickly and integrate with your existing data stack, including ELT (extract, load, transform) tools. For more on how Propel can help you, join the waitlist.

Related Content

Abstract Databases

How-to

How to set up development and production environments in Snowflake

If you use Snowflake to managing your data warehouse, you can set up either a single account or multiple accounts for your development.

Propel Data offers a blazing fast GraphQL API for building data apps from data that organizations already have in Snowflake data warehouse, as illustrated by this photograph of a laptop showing a real-time product dashboard with analytical reports and data visualization.

How-to

How to build Snowflake data apps with GraphQL

Need to build a Snowflake data app? Here's how to create and query a Metric on top of Snowflake data warehouse using Propel’s GraphQL API.