Table of Contents
Implementing a role-based access control (RBAC) system is essential for many web applications that require different levels of user permissions. In this article, we will explore a real-world example of building such a system using TypeScript and Express.js, a popular Node.js framework.
Prerequisites
- Basic knowledge of TypeScript and Node.js
- Experience with Express.js framework
- Understanding of user authentication and authorization concepts
Project Setup
Start by creating a new directory for your project and initializing a new Node.js project:
mkdir role-based-access && cd role-based-access
npm init -y
Install necessary dependencies:
npm install express typescript ts-node @types/express @types/node --save-dev
Create a tsconfig.json file for TypeScript configuration:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
Defining User Roles and Middleware
Define roles and create middleware to check user permissions:
// src/roles.ts
export type Role = 'admin' | 'editor' | 'viewer';
export const rolesPermissions: Record = {
admin: ['create', 'read', 'update', 'delete'],
editor: ['read', 'update'],
viewer: ['read']
};
// src/middleware.ts
import { Request, Response, NextFunction } from 'express';
export function authorize(allowedRoles: Role[]) {
return (req: Request, res: Response, next: NextFunction) => {
const userRole: Role = req.headers['x-user-role'] as Role;
if (!userRole || !allowedRoles.includes(userRole)) {
return res.status(403).json({ message: 'Forbidden' });
}
next();
};
}
Creating the Express Server
Set up the server and define routes with role-based access control:
// src/index.ts
import express from 'express';
import { rolesPermissions } from './roles';
import { authorize } from './middleware';
const app = express();
const PORT = 3000;
app.use(express.json());
app.get('/public', (req, res) => {
res.send('Public Content Accessible to All');
});
app.get('/admin', authorize(['admin']), (req, res) => {
res.send('Admin Content');
});
app.get('/edit', authorize(['admin', 'editor']), (req, res) => {
res.send('Editor and Admin Content');
});
app.get('/view', authorize(['admin', 'editor', 'viewer']), (req, res) => {
res.send('Content for All Roles');
});
app.listen(PORT, () => {
console.log(\`Server is running on port \${PORT}\`);
});
Testing the System
Use tools like Postman or curl to test different endpoints by setting the x-user-role header:
curl -H "x-user-role: admin" http://localhost:3000/admin
curl -H "x-user-role: viewer" http://localhost:3000/admin
Conclusion
Building a role-based access system with TypeScript and Express.js is straightforward with middleware functions that check user roles. This setup can be expanded with real authentication mechanisms, database integrations, and more complex permission schemes to suit your application's needs.