How to Implement OAuth in an Express App Using GitHub

OAuth 2.0 is a standard that lets third-party applications access data from web apps securely. You can use it to fetch data including profile information, schedules, etc. that’s hosted on other web apps like Facebook, Google, and GitHub. A service can do this on behalf of a user without exposing their credentials to the third-party application.
Learn how to implement OAuth in an Express app using GitHub as an OAuth provider in a few steps.
The OAuth Flow
In a typical OAuth flow, your site provides an option for users to log in with their third-party account from a provider like GitHub or Facebook. A user can start this process by clicking a relevant OAuth login button.
This redirects them from your application to the OAuth provider’s website and presents them with a consent form. The consent form contains all the information you want to access from the user, which could be their emails, pictures, schedules, etc.
If the user authorizes your application, the third party will redirect them back to your application with a code. Your application can then exchange the received code for an access token which it can then use to access available user data.
Implementing this flow in an Express application involves a few steps.
Step 1: Setting Up Development Environment
First, create an empty project directory and cd into the created directory.
For example:
mkdir github-app
cd github-app
Next, initialize npm in your project by running:
npm init -y
This command creates a package.json file that contains details about your project like the name, version, etc.
This tutorial will feature the use of the ES6 module system. Set this up by opening your package.json file and specifying “type”: “module” in the JSON object.
Step 2: Installing Dependencies
You’ll need to install a few dependencies for your server to work properly:
- ExpressJS: ExpressJS is a NodeJS framework that provides a robust set of features for web and mobile applications. Using Express will simplify your server creation process.
- Axios: Axios is a promise-based HTTP client. You will need this package to make a POST request for an access token to GitHub.
- dotenv: dotenv is a package that loads environment variables from a .env file into the process.env object. You will need it to hide important information about your application.
Install them by running:
npm install express axios dotenv
Step 3: Creating an Express App
You need to create a basic Express server to handle and make requests to the OAuth provider.
First, create an index.js file in your project’s root directory containing the following:
import express from "express";
import axios from "axios";
import * as dotenv from "dotenv";
dotenv.config();const app = express();
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log(`App is running on port ${port}`);
});
This code imports the express library, instantiates an express instance, and starts listening for traffic on port 3000.
Step 4: Creating Route Handlers
You’ll need to create two route handlers to handle the OAuth flow. The first redirects the user to GitHub and requests authorization. The second handles the redirect back to your app and makes the request for the access token when a user authorizes your application.
The first route handler should redirect the user to https://github.com/login/oauth/authorize?parameters.
You’ll need to pass a set of required parameters to GitHub’s OAuth URL, which include:
- Client Id: This refers to the ID your OAuth application receives when registered on GitHub.
- Scope: This refers to a string that specifies the amount of access an OAuth app has to a user’s information. You can find a list of available scopes in GitHub’s OAuth documentation. Here you will be using a “read:user” scope, which grants access to read a user’s profile data.
Add the following code to your index.js file:
app.get("/auth", (req, res) => {
const params = {
scope: "read:user",
client_id: process.env.CLIENT_ID,
};
const urlEncodedParams = new URLSearchParams(params).toString();
res.redirect(`https://github.com/login/oauth/authorize?${urlEncodedParams}`);
});
This code implements the first route handler. It stores the required parameters in an object, converting them to a URL-encoded format using the URLSearchParams API. It then adds these parameters to GitHub’s OAuth URL and redirects the user to GitHub’s consent page.
Add the following code to your index.js file for the second route handler:
app.get("/github-callback", (req, res) => {
const { code } = req.query;const body = {
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
code,
};
let accessToken;
const options = { headers: { accept: "application/json" } };
axios
.post("https://github.com/login/oauth/access_token", body, options)
.then((response) => response.data.access_token)
.then((token) => {
accessToken = token;
res.redirect(`/?token=${token}`);
})
.catch((err) => res.status(500).json({ err: err.message }));
});
The second route handler will extract the code returned from GitHub in the req.query object. It then makes a POST request using Axios to “https://github.com/login/oauth/access_token” with the code, client_id, and client_secret.
The client_secret is a private string you’ll generate when you create a GitHub OAuth application. When the access_token is successfully fetched, it is saved to a variable for later use. The user is finally redirected to your application with the access_token.
Step 5: Creating a GitHub Application
Next, you’ll need to create an OAuth application on GitHub.
First, log into your GitHub account, then go to Settings, scroll down to Developer settings, and select OAuth Apps. Finally, click on “Register a new application.”
GitHub will provide you with a new OAuth application form like this:
Fill in the required fields with your desired details. The “Homepage URL” should be “http://localhost:3000”. Your “Authorization callback URL” should be “http://localhost:3000/github-callback”. You can also optionally enable device flow, allowing you to authorize users for a headless app, such as a CLI tool or Git credential manager.
The device flow is in public beta and subject to change.
Finally, hit the Register application button.
GitHub will direct you to a page with your client_id and an option to generate your client_secret. Copy your client_id, generate your client_secret, and copy it too.
Create a .env file and store the client_id and client_secret inside it. Name these variables CLIENT_ID and CLIENT_SECRET respectively.
Your OAuth flow is now complete, and you can now make requests with the access token to read user data (the scope you specified earlier).
The Importance of OAuth 2.0
Using OAuth 2.0 in your application greatly simplifies the task of implementing an authentication flow. It secures your customers’ user data using the Secure Sockets Layer (SSL) standard, ensuring that they remain private.