Follow

Follow

Authorize NodeJS APIs using Authorizer

Lakhan Samani's photo
Lakhan Samani
·Jan 12, 2023·

4 min read

Table of contents

  • Step 1: Setup Authorizer Instance
  • Step 2: Create Express App
  • Step 3: Create Authorization Middleware
  • Step 4: Add auth middleware to APIs
  • Step 5: Test the API

In this blog post, we will learn how to authorize users for API calls, based on valid sessions and roles using Authorizer. Authorizer is an open-source database-independent auth solution. You can bring your database and have authentication and authorization service ready out of the box.

For the demo purpose, we will be using [Express](https://expressjs.com/) server and writing a middleware that will validate user sessions & roles based on the JWT (JSON Web Token) in the Authorization header.

Refer to the source code on github.

Step 1: Setup Authorizer Instance

Deploy production-ready Authorizer instance using one-click deployment options available below

Infra providerOne-click linkAdditional information
Railway.appdocs
Herokudocs
Renderdocs

For more information & deployment options like docker / Kubernetes / helm charts refer to the docs

Configure Instance

  • Open the Authorizer instance endpoint in a browser

  • SignUp as an Admin with a secure password

  • Configure environment variables from the dashboard. Check env docs for more information.

    Note: DATABASE_URL , DATABASE_TYPE , REDIS_URL are the variables that can only be configured as the authorizer instance's system environment variable.

Step 2: Create Express App

Note: This step is optional if you already have a Nodejs application up and running

  • Setup project

      # Create directory
      mkdir my-apis
    
      # Change directory
      cd my-apis
    
      # Initialize nodejs APP
      npm init -y
    
      # Install express
      npm install express
    
      # Create index.js
      touch index.js
    
  • Add Start Command to package.json

      {
        "name": "my-apis",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
          "start": "node index.js",
          "test": "echo \"Error: no test specified\" && exit 1"
        },
        "keywords": [],
        "author": "Lakhan Samani",
        "license": "ISC",
        "dependencies": {
          "express": "^4.18.2"
        }
      }
    
  • Setup Express App and Create a basic API in index.js

      // index.js
      const express = require('express');
    
      const app = express();
      const port = `3000`;
    
      app.get('/', (req, res) => {
        res.send('Hello World');
      });
    
      app.listen(port, () => {
        console.log(`[server]: Server is running at http://localhost:${port}`);
      });
    

Step 3: Create Authorization Middleware

  • Install @authorizerdev/authorizer-js

      npm i --save @authorizerdev/authorizer-js
    
  • Create auth_middleware.js

      touch auth_middleware.js
    
  • Implement authorization middleware

      // auth_middleware.js
    
      const { Authorizer } = require("@authorizerdev/authorizer-js");
    
      const authRef = new Authorizer({  
        authorizerURL: "AUTHORIZER_URL_FROM_STEP 1",
        redirectURL: "FRONTEND_URL",
        clientID: "AUTHORIZER_CLIENT_ID FROM DASHBOARD"
      });
    
      const authMiddleware = async (req, res, next) => {
          const authHeader = req.headers.authorization;
        if (!authHeader) {
          return res.status(403).json({ error: "Authorization not found" });
        }
    
        const splitHeader = authHeader.split(" ");
        if (splitHeader.length != 2) {
          return res.status(403).json({ error: "Invalid auth header" });
        }
    
        if (splitHeader[0].toLowerCase() != "bearer") {
          return res.status(403).json({ error: "Bearer token not found" });
        }
    
        const token = splitHeader[1];
        // Validate jwt token via authorizer sdk
        try {
          const res = await authRef.validateJWTToken({
            token,
            token_type: "id_token", // This can be access_token, refresh_token
             // roles: [user] // specify roles that you want to validate jwt for, by default it will just verify jwt.
          });
          req.user = res.claims;
        } catch (err) {
          console.error(err);
          return res.status(403).json({ error: "Invalid JWT token" });
        }
    
        next();
      }
    
      module.exports = authMiddleware
    

Step 4: Add auth middleware to APIs

Update index.js with following content

// index.js
const express = require('express');
const authMiddleware = require('./auth_middleware')

const app = express();
const port = `3000`;

app.get('/', authMiddleware, (req, res) => {
  res.send('Hello World');
});

app.listen(port, () => {
  console.log(`[server]: Server is running at http://localhost:${port}`);
});

Step 5: Test the API

  • Start API Server

      npm start
    
  • Make a curl request

      curl http://localhost:3000
    

Note: This will return an error, as we have not specified the Authorization header with a valid JWT token

  • For this test to pass we need to have a valid JWT token, so let's generate a valid JWT by making a login call to the authorizer server

      # Replace Authorizer URL from step 1
      # Replace credentials with right credentials in --data-raw (demo@yopmail.com, Test@123#)
      # If you have no user on your instance, first signup using AUTHORIZER_URL_FROM_STEP_1/app?redirect_uri=AUTHORIZER_URL_FROM_STEP_1/app
    
      curl --location --request POST 'AUTHORIZER_URL_FROM_STEP_1/graphql' \
      --header 'Content-Type: application/json' \
      --data-raw '{"query":"mutation login {\n  login(params: {\n    email: \"demo@yopmail.com\",\n    password: \"Test@123#\"\n  }) {\n    id_token\n  }\n}","variables":{}}'
    

    This should return an id_token in response, as shown in the screenshot below. Copy the id_token from the response and pass it to our nodeJS API server

  • Test the API

      curl --header 'Authorization: Bearer TOKEN_COPIED_FROM_ABOVE_STEP' http://localhost:3000
    

That's all I hope this helps you authorize your APIs easily and make them secure based on the correct session and roles.

For more information check out the links below.

 
Share this