If you're tired of writing repetitive access checks in your Express.js routes, express-access is a lightweight package that brings clean and dynamic role-based access control (RBAC) to your server โ without the boilerplate.
๐ Why use express-access?
- โ Clean route definitions with permission checks
- ๐ Fully customizable auth and permission logic
- ๐งฉ Integrates with any database (SQL, NoSQL, ORM, etc.)
- ๐ฆ Lightweight with zero dependencies
โจ Quick Example
import express from 'express';
import access from 'express-access';
const app = express();
app.use(access.config({
authMiddleware: async (req, res, next) => {
// Simulate user retrieval (e.g., from JWT or session)
const uid = 'user1';
const user = await db.users.findById(uid);
req.user = { uid: user.id, roleId: user.role_id };
next();
},
checkPermission: async (user, permissionId) => {
const permissions = await db.role_permissions.findAll({
where: { role_id: user.roleId },
attributes: ['permission_id'],
});
const allowed = permissions.map(p => p.permission_id);
return allowed.includes(permissionId);
},
}));
app.get('/', (req, res) => {
res.send('Public Route');
});
// Protected route with permission "post:edit"
app.access.get('/edit-post', 'post:edit', [
(req, res) => {
res.json({ success: true, message: 'Post editing allowed' });
}
]);
app.listen(3000, () => console.log('Server running on port 3000'));
๐ง How It Works
express-access
lets you define:
-
authMiddleware
: You attach the authenticated user object (e.g., from JWT/session) toreq.user
. -
checkPermission
: You define how a permission string like'post:edit'
is validated against the current user. This function receives the full user object โ not just a user ID โ so you can access roles, groups, or even account types.
๐๏ธ Suggested Database Structure
A common and scalable RBAC setup:
users
๐งช Real Flow Example
Letโs say user1
makes a request to /edit-post
:
-
authMiddleware
attaches:
req.user = { uid: 'user1', roleId: 'editor' };
-
checkPermission
pulls all permission IDs for the roleeditor
:
['post:read', 'post:edit']
Since
'post:edit'
exists, access is granted.The handler runs. โ Clean and secure.
๐ก Tips
- You can cache permissions per role for performance (e.g., Redis).
- You can easily support multiple roles per user.
- Permissions can be strings like post:edit, user:create, etc.
- Works great with Sequelize, Prisma, or raw queries.
๐ฆ Install
npm install express-access
๐งฉ Open Source
Feel free to contribute or check out the full source code on GitHub:
๐ https://github.com/bahador-r/express-access
๐ Final Thoughts
RBAC shouldnโt be hard to implement. express-access gives you the building blocks to do it elegantly, with full control over your logic and database. Perfect for SaaS products, admin panels, APIs, and anywhere you need clean authorization.
Top comments (0)