Authgear
Start BuildingHomePortalCommunity
  • Authgear Overview
  • Get Started
    • Start Building
    • 5-Minute Guide
    • Single-Page App
      • JavaScript (Web)
      • React
      • Angular
      • Vue
    • Native/Mobile App
      • iOS SDK
      • Android SDK
        • Android Kotlin coroutine support
        • Android OKHttp Interceptor Extension (Optional)
      • Flutter SDK
      • React Native SDK
      • Ionic SDK
      • Xamarin SDK
      • Using Authgear without SDK (Client side)
    • Regular Web App
      • Express
      • Next.js
      • Python Flask App
      • Java Spring Boot
      • ASP.NET Core MVC
      • Laravel
      • PHP
    • Backend/API Integration
      • Validate JWT in your application server
      • Forward Authentication to Authgear Resolver Endpoint
    • AI Coding tools
      • Cursor/Windsurf
  • How-To Guides
    • Authenticate
      • Add Passkeys Login
      • Add WhatsApp OTP Login
      • Add Email Magic Link Login
      • Add Biometric Login
      • Add Anonymous Users
      • Add authentication to any web page
      • Enable Two-Factor Authentication (2FA)
      • How to Use the OAuth 2.0 State Parameter
      • Reauthentication
      • How to Use Social/Enterprise Login Providers Without AuthUI
      • Passwordless Login for Apple App Store Review
      • Setup local development environment for Cookie-based authentication
      • Forgot/Reset Password settings
      • Phone number validation
      • Set Password Expiry
    • Single Sign-on
      • App2App Login
      • Pre-authenticated URLs
      • SSO between Mobile Apps / Websites
      • Force Authgear to Show Login Page
      • Single Sign-On with OIDC
      • Single Sign-On with SAML
        • Use Authgear as SAML Identity Provider for Salesforce
        • Use Authgear as SAML Identity Provider for Dropbox
        • SAML Attribute Mapping
    • Social Login / Enterprise Login Providers
      • Social Login Providers
        • Connect Apps to Apple
        • Connect Apps to Google
        • Connect Apps to Facebook
        • Connect Apps to GitHub
        • Connect Apps to LinkedIn
        • Connect Apps to WeChat
      • Enterprise Login Providers
        • Connect Apps to Azure Active Directory
        • Connect Apps to Microsoft AD FS
        • Connect Apps to Azure AD B2C
      • Force Social/Enterprise Login Providers to Show Login Screen
    • Built-in UI
      • Branding in Auth UI
      • User Settings
      • Privacy Policy & Terms of Service Links
      • Customer Support Link
      • Custom Text
    • Custom UI
      • Authentication Flow API
      • Implement Authentication Flow API using Express
      • Implement Authentication Flow API using PHP
      • Add Custom Login/Signup UI to Native Apps
      • Manually Link OAuth Provider using Account Management API
      • Implement a custom account recovery UI using Authentication Flow API
    • Integrate
      • Add custom fields to a JWT Access Token
      • User Analytics by Google Tag Manager
      • Track User Before and After Signup
      • Custom domain
      • Custom Email Provider
      • Custom SMS Provider
        • Twilio
        • Webhook/Custom Script
    • Monitor
      • Audit Log For Users Activities
      • Audit Log for Admin API and Portal
      • Analytics
    • User Management
      • Account Deletion
      • Import Users using User Import API
      • Export Users using the User Export API
      • Manage Users Roles and Groups
      • How to Handle Password While Creating Accounts for Users
    • User Profiles
      • What is User Profile
      • Access User Profiles
      • Update User Profiles
      • Profile Custom Attributes
      • Update user profile on sign-up using Hooks
    • Events and Hooks
      • Event List
      • Webhooks
      • JavaScript / TypeScript Hooks
      • Only Allow Signups from Inside the Corporate Network using Hooks
    • Mobile Apps
      • Use SDK to make authorized API calls to backend
      • Force authentication on app launch
      • Customize the Login Pop-up / Disable the login alert box
    • Languages and Localization
    • Custom Email and SMS Templates
    • Directly accessing Authgear Endpoint
    • Migration
      • Bulk migration
      • Rolling migration
      • Zero-downtime migration
    • Troubleshoot
      • How to Fix SubtleCrypto: digest() undefined Error in Authgear SDK
      • How to Fix CORS Error
  • Concepts
    • Identity Fundamentals
    • Authgear use cases
    • User, Identity and Authenticator
  • Security
    • Brute-force Protection
    • Bot Protection
    • Non-HTTP scheme redirect URI
    • Password Strength
  • Reference
    • APIs
      • Admin API
        • Authentication and Security
        • API Schema
        • Admin API Examples
        • Using global node IDs
        • Retrieving users using Admin API
        • User Management Examples
          • Search for users
          • Update user's standard attributes
          • Update user's picture
          • Generate OTP code
      • Authentication Flow API
      • OAuth 2.0 and OpenID Connect (OIDC)
        • UserInfo
        • Supported Scopes
      • User Import API
      • User Export API
    • Tokens
      • JWT Access Token
      • Refresh Token
    • Glossary
    • Billing FAQ
    • Rate Limits
      • Account Lockout
  • Client App SDKs
    • Javascript SDK Reference
    • iOS SDK Reference
    • Android SDK Reference
    • Flutter SDK Reference
    • Xamarin SDK Reference
  • Deploy on your Cloud
    • Running locally with Docker
    • Deploy with Helm chart
    • Authenticating HTTP request with Nginx
    • Configurations
      • Environment Variables
      • authgear.yaml
      • authgear.secrets.yaml
    • Reference Architecture Diagrams
      • Google Cloud Reference Architecture
      • Azure Reference Architecture
      • AWS Reference Architecture
      • Throughput Scaling Reference
Powered by GitBook
On this page
  • What You Will Learn
  • Pre-requisites
  • Setup Application in Authgear
  • Create an application in the Portal
  • Configure Authorize Redirect URI
  • How to Add User Authentication to Express.js App using Authgear
  • Step 1: Create Express App
  • Step 2: Implement Login Route
  • Step 3: Exchange Authorization Code For Access Token
  • Step 4: Get User Info
  • Step 5: Logout
  • Step 6: Refresh Access Token
  • Next steps, Calling an API
  • Conclusion

Was this helpful?

Edit on GitHub
  1. Get Started
  2. Regular Web App

Express

Authentication for Express.JS apps with Authgear and OAuth2

PreviousRegular Web AppNextNext.js

Last updated 4 months ago

Was this helpful?

Authgear makes it easy to add user authentication to a regular web app that is not powered by any framework. You can do this by integrating Authgear into your application as an OIDC identity provider.

In this post, you'll learn how to add user authentication to an Express.js application using Authgear.

What You Will Learn

  • How to create an Authgear Application.

  • How to add User Login to an Express app using Authgear.

  • How to request user info from Authgear.

Pre-requisites

You'll need the following to follow along with this tutorial:

  • Node.js Installed

  • A free Authgear account. Sign up for one .

Follow this guide to add user authentication to an Express application using Authgear in 🕐 15-minute.

Check out and clone .

Setup Application in Authgear

Login to your Authgear account (you can sign up for one ) to perform the steps in this section.

Create an application in the Portal

In this step, we'll create the Authgear client application that we'll use later to connect Authgear to the Express application.

After you log in to Authgear Portal, select a project then navigate to Applications on the left menu bar.

Next, click on the ⊕Add Application button on the top toolbar to open the New Application page.

Enter an application name (for example: "My App") and select OIDC/SAML Client Application as the Application Type. Click Save to create the app.

On the next screen, you'll see links to tutorials for different frameworks. Click Next to skip to the application configuration page.

Note the Client ID and Client Secret for your new application as you'll use in a later step to configure your Express app.

Configure Authorize Redirect URI

The Authorized Redirect URI should be a page on your Express application where you make an HTTP(S) request to the Authgear token endpoint and exchange an Authorization Code for an Access Token.

For our demo Express application for this guide, this URL will be http://localhost:3000/auth-redirect. So, scroll to the URI section of your application configuration page in the Authgear Portal and add http://localhost:3000/auth-redirect as an authorized redirect URI.

Click Save to keep your changes.

How to Add User Authentication to Express.js App using Authgear

In this section, we'll be building a simple Express app that has the following features:

  • A landing page with a login link that takes users to the login route.

  • A /start-login route that initiates the authentication flow.

  • Logic that exchanges the authorization code from Authgear for an access token.

  • A page that uses that access token to fetch user info from Authgear.

  • A logout button to end the current user session.

  • Refresh access token.

Step 1: Create Express App

It is now time to create the Express app that will be connecting to our Authgear client application. Run the following commands to create a new folder for the project and set it as your current working directory:

# create project directory
mkdir my-express-app
#set project directory as current working directory
cd my-express-app

Install basic project dependencies

Next, install the Express npm package and other dependency packages like axios, nodemon, session, and dotenv.

We'll be using the axios library to make HTTP requests in the example app. We'll also use nodemon to add hot reload to our development environment. Run the following commands from the root of your Express project directory to install Express and other dependencies:

# Generate package.json
npm init -y
# Install Express 
npm install express
# Install axios
npm install axios
# Install express-session
npm install express-session
# Install dotenv
npm install dotenv
# Install Nodemon (Used to add hot road to JavaScript development)
npm install -D nodemon

Create app.js file

Once Express and the other dependencies are installed, create a new app.js file in the root of your project folder and add the following code to the file:

//app.js
const express = require('express');
const axios = require("axios");
const session = require("express-session");
require("dotenv").config();

const app = express();
const port = process.env.PORT || 3000;
app.use(express.urlencoded({ extended: true }));
app.use(
  session({
    secret: "your_strong_secret_key", // Replace with a strong, randomly generated secret
    cookie: {},
  })
);

app.get("/", async (req, res) => {
    res.send(`
        <div style="max-width: 650px; margin: 16px auto; background-color: #EDEDED; padding: 16px;">
          <p>Hi there!</p>
          <p>This demo app shows you how to add user authentication to your Express app using Authgear</p>
            <p>Checkout <a href="https://docs.authgear.com">docs.authgear.com</a> to learn more about adding Authgear to your apps.</p>
          <a href="/login">Login</a>
        </div>
      `);
  });

app.get("/login", async(req, res) => {
    // TODO add implementation here
});

app.get("/auth-redirect", async(req, res) => {
    // TODO add implementation here
});

app.listen(port, () => {
    console.log(`server started on port ${port}!`);
});

Update package.json

Add the following code to the scripts section of the package.json file in the root directory of your Express project:

"start": "node app.js",
"dev": "nodemon app.js"

Checkpoint

Now run the npm run dev command and you should get a page like this on a web browser when you visit localhost:3000:

Step 2: Implement Login Route

Here we'll be implementing the login route in our Express app. This route will initiate the authentication flow by redirecting the user's browser to the login page (AuthUI). This process involves redirecting the user to your Authgear project/client application's authorization URL (https://<AUTHGEAR_ENDPOINT>/oauth2/authorize ).

Update the code for the app.get("/login", ...) route to the following:

app.get("/login", async(req, res) => {
    const scopes = "openid offline_access";
    const authorizedUrl = new URL("/oauth2/authorize", process.env.AUTHGEAR_ENDPOINT);
    authorizedUrl.searchParams.set('client_id', process.env.AUTHGEAR_CLIENT_ID);
    authorizedUrl.searchParams.set('redirect_uri', process.env.AUTHGEAR_REDIRECT_URL);
    authorizedUrl.searchParams.set('response_type', 'code');
    authorizedUrl.searchParams.set('scope', scopes);
    res.redirect(authorizedUrl);
});

Create a .env file on the root directory of your project and add your Authgear client application configuration (Client ID, secret, endpoint) using the following fields:

AUTHGEAR_CLIENT_ID=<CLIENT_ID>
AUTHGEAR_CLIENT_SECRET=<CLIENT_SECRET>
AUTHGEAR_ENDPOINT=<AUTHGEAR_ENDPOINT>
AUTHGEAR_REDIRECT_URL=http://localhost:3000/auth-redirect

Now if you save your code and restart your app, clicking on the Login link should redirect to the Authgear authorization page.

On successful login, an authorization code will be sent back to your Express application.

Step 3: Exchange Authorization Code For Access Token

In this step, we will be exchanging the authorization code for an access code that users can later use to access protected resources.

Update the code for the app.get("/auth-redirect", ...) route to the following:

app.get("/auth-redirect", async(req, res) => {
        if (req.query.code != null) {
            const data = {
              client_id: process.env.AUTHGEAR_CLIENT_ID,
              client_secret: process.env.AUTHGEAR_CLIENT_SECRET,
              code: req.query.code,
              grant_type: 'authorization_code',
              response_type: 'code',
              redirect_uri: process.env.AUTHGEAR_REDIRECT_URL
            };
        
            try {
              const tokenUrl = new URL("/oauth2/token", process.env.AUTHGEAR_ENDPOINT);
              const getToken = await axios.post(tokenUrl, data, {
                headers: { "Content-Type": "application/x-www-form-urlencoded" }
              });
        
              const accessToken = getToken.data.access_token;
        
              req.session.access_token = accessToken;
              res.redirect("/");

            } catch (error) {
              res.send("An error occurred! Login could not complete. Error data: " + error);
            }
          } else {
            res.send("No Authorization code in URL");
          }
        
});

The above code sends an HTTP POST request to the token endpoint (https://<AUTHGEAR_ENDPOINT>/oauth2/token). The authorization code we got from the previous step is sent along with other client credentials in the HTTP request body. The header should contain "Content-Type": "application/x-www-form-urlencoded"

A valid access token is returned in the response to the HTTP(S) request in response.data.access_token. In the above code sample, we've saved this access token temporally using express-session so we can access it from "/" route after redirecting the user.

We can now use this access token to make authenticated requests to protected resources in our app or from the Authgear User Info endpoint. In the next step, we'll attempt to get the current user's info from Authgear using the access token.

Step 4: Get User Info

Authgear provides an endpoint where your application can request user info (https://<AUTHGEAR_ENDPOINT>/oauth2/userinfo). This endpoint will return the user's details on Authgear like their email address, gender, full name, and more.

To get user info in our example app, update the app.get("/", ...) app.js, to use the following conditional statement to render a different block of code when a valid access token is set for the current session:

app.get("/", async (req, res) => {
  if (req.session.access_token != null) {
    const accessToken = req.session.access_token;
    //Now use access token to get user info.
  try {
        const userInfoUrl = new URL(
            "/oauth2/userinfo",
            process.env.AUTHGEAR_ENDPOINT
          );
          const getUserInfo = await axios.get(userInfoUrl, {
            headers: { Authorization: "Bearer " + accessToken },
          });
          const userInfo = getUserInfo.data;
          res.send(`
              <div style="max-width: 650px; margin: 16px auto; background-color: #EDEDED; padding: 16px;">
                <p>Welcome ${userInfo.email}</p>
                <p>User Info:</p>
                <div>
                  <pre>${JSON.stringify(userInfo, null, 2)}</pre>
                </div>
                  <p> 
                      <a href="/logout">Logout</a>
                  </p>
              </div>
          `);
    }
    catch (error) {
        res.send("Unable to get User Info: " + error);
    }
  } else {
    res.send(`
            <div style="max-width: 650px; margin: 16px auto; background-color: #EDEDED; padding: 16px;">
              <p>Hi there!</p>
              <p>This demo app shows you how to add user authentication to your Express app using Authgear</p>
                <p>Checkout <a href="https://docs.authgear.com">docs.authgear.com</a> to learn more about adding Authgear to your apps.</p>
              <a href="/login">Login</a>
            </div>
          `);
  }
});

Here our app sends another HTTP(S) request, but this time to the user info endpoint and the request type is GET. The access token is sent as a Bearer authorization header.

At this point, save all changes and restart the application. Try logging in all over again, at the end you should be greeted with "Welcome [your email address]" and a dump of the response from the UserInfo endpoint if the access token in your authorization header is valid.

Step 5: Logout

To allow your users log out, add a new /logout route to your Express application. Within the route, you'll implement code that will call express-session destroy() method to delete the access token from the session. Then you'll redirect the user to Authgear's logout endpoint to log the user's session on Authgear.

To redirect the user back to your Express app after they logout, add http://localhost:3000 as a Post Logout Redirect URI for your client application in Authgear Portal.

Your implementation of the logout route should look like this:

app.get("/logout", async (req, res) => {
  const accessToken = req.session.access_token;
  const endSessionUrl = new URL(
    "/oauth2/end_session",
    process.env.AUTHGEAR_ENDPOINT
  );
  endSessionUrl.searchParams.set("post_logout_redirect_uri", "http://localhost:3000");
  
  // Remove access token, and refresh token from express-session
  req.session.destroy();
  
  res.set("Authorization", "Bearer " + accessToken);
  res.redirect(endSessionUrl);
});

Finally, place a link to the logout route below the </prev> tag using the following code:

<a href="/logout">Logout</a>

Step 6: Refresh Access Token

Note that you must include offline_access in the scope parameter of your authorization request to get a refresh token from Authgear.

We recommend that you check that an access token is still valid before using it in your authorization header to access protected resources like the User Info endpoint.

To add the capability of refreshing an expired access token to our Express app, add the following function to app.js:

const refreshAccessTokenIfExpired = async (refreshToken, expiresAt, req) => {
    const currentTime = (new Date(Date.now()).getTime());
    if (expiresAt<currentTime) {
        const tokenUrl = new URL("/oauth2/token", process.env.AUTHGEAR_ENDPOINT);
        const data = {
            client_id: process.env.AUTHGEAR_CLIENT_ID,
            client_secret: process.env.AUTHGEAR_CLIENT_SECRET,
            grant_type: "refresh_token",
            refresh_token: refreshToken
          };

          try {
            const getToken = await axios.post(tokenUrl, data, {
              headers: { "Content-Type": "application/x-www-form-urlencoded" },
            });
        
            const accessToken = getToken.data.access_token;
            const expiresAt = new Date(Date.now()).getTime() + getToken.data.expires_in * 1000;
        
            req.session.access_token = accessToken;
            req.session.expire_at = expiresAt;
            return accessToken;
          } catch (error) {
            throw new Error('Failed to refresh access token: ' + error);
          }
    } else {
        return req.session.access_token;
    }
};

Next, find the following line within the app.get("/auth-redirect", ...) route:

req.session.access_token = accessToken;

Add the following code just after the above line:

req.session.expire_at = new Date(Date.now()).getTime() + getToken.data.expires_in * 1000;
req.session.refresh_token = getToken.data.refresh_token;

Finally, find the following line in the app.get("/", ...) route:

const accessToken = req.session.access_token;

Replace the above line with the following code:

const accessToken = await refreshAccessTokenIfExpired(req.session.refresh_token, req.session.expire_at, req);

Now our Express app gets an access token by first calling the new refreshAccessTokenIfExpired() method. If the current access token is expired, the method will make a request to Authgear's token endpoint for a new access token. This request needs to have a grant_type of refresh_token, and the refresh_token should be included in the POST request body.

Next steps, Calling an API

To access restricted resources on your backend application server, the HTTP requests should include the access token in their Authorization headers.

For example:

axios.get("https://<your_backend_url>", {
        headers: { Authorization: "Bearer " + accessToken },
      });

Conclusion

And there you have it, you've successfully added user authentication to your Express app using Authgear as the OAuth provider.

You can add so much more to your app with the new Authgear authentication, like protecting your own app endpoint with the access code. You can also store the access token securely to persist the user session using express-session and cookies.

You can get the value for Client ID and Client Secret from the configuration page for the client application you created in the earlier step, . The Authgear Endpoint looks like https://project_id.authgear.cloudif you are using Authgear Cloud version.

After the user logs in and grants authorization to your app on the Login page, they are redirected back to the . In addition to this redirect, an authorization code is sent via a code URL query parameter.

An access token is usually only valid for a short period. However, you can use the refresh token, also included in the response from the token endpoint in to request a new access token.

The above code will store the values of refresh_token and expires_in that were returned in in express-session. To convert expire_in to a time in the future, we multiply it by 1000 and add that to the current time.

See more about refreshing access tokens .

Here's a link to the complete code for .

here
the Sample Project on GitHub
here
here
our example code on Github
Create an application in the Portal
redirect URL you specified earlier
step 3
step 3
navigate to applications
new app form oidc app
authgear set redirect uri
express demo app homepage
authui login page
express demo
set post logout redirect uri