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
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
mkdir my-apis
cd my-apis
npm init -y
npm install express
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
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
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];
try {
const res = await authRef.validateJWTToken({
token,
token_type: "id_token",
});
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
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
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
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.