Authorize NodeJS APIs using Authorizer
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 provider | One-click link | Additional information |
Railway.app | Deploy now | docs |
Heroku | Deploy now | docs |
Render | Deploy now | docs |
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 theid_token
from the response and pass it to our nodeJS API serverTest 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.
Website: https://authorizer.dev
React SDK: github.com/authorizerdev/authorizer-react
Javascript SDK: github.com/authorizerdev/authorizer-js
Youtube: https://youtube.com/playlist?list=PLSQGbUjHc6bpaAgCiQPzNxiUPr7SkDAFR
Discord: https://discord.gg/Zv2D5h6kkK
Github Sponsorship: github.com/sponsors/authorizerdev
Buy me Coffee: https://www.buymeacoffee.com/lakhansamani