Home   nodejs  

How to implement role based access control in nodejs express app

Implementing role-based access control (RBAC) involves managing user roles and permissions both on the frontend (React) and backend (Express). Here’s a basic guide on how to implement RBAC in a React and Express application:

Backend (Express)

  1. Define Roles and Permissions: Decide on the roles (e.g., admin, user) and their corresponding permissions (e.g., read, write) in your application.

  2. User Model: Include role information in your user model. Example using Mongoose:

    const mongoose = require('mongoose');
    
    const userSchema = new mongoose.Schema({
        username: { type: String, required: true },
        email: { type: String, required: true },
        password: { type: String, required: true },
        role: { type: String, enum: ['user', 'admin'], default: 'user' }
    });
    
    module.exports = mongoose.model('User', userSchema);
    
  3. Authentication Middleware: Create a middleware to check role-based access:

    // middleware/authenticate.js
    const jwt = require('jsonwebtoken');
    
    function authenticate(role) {
        return function(req, res, next) {
            const token = req.header('Authorization');
    
            if (!token) {
                return res.status(401).json({ message: 'Unauthorized' });
            }
    
            try {
                const decoded = jwt.verify(token, process.env.JWT_SECRET);
                req.user = decoded.user;
    
                if (role && req.user.role !== role) {
                    return res.status(403).json({ message: 'Forbidden' });
                }
    
                next();
            } catch (err) {
                console.error(err);
                res.status(500).json({ message: 'Server Error' });
            }
        };
    }
    
    module.exports = authenticate;
    
  4. Route Protection: Protect routes using the authentication middleware:

    // routes/secureRoute.js
    const express = require('express');
    const router = express.Router();
    const authenticate = require('../middleware/authenticate');
    
    // Route accessible only to admin
    router.get('/admin', authenticate('admin'), (req, res) => {
        res.json({ message: 'Admin Route' });
    });
    
    // Route accessible to all authenticated users
    router.get('/user', authenticate(), (req, res) => {
        res.json({ message: 'User Route' });
    });
    
    module.exports = router;
    

Frontend (React)

  1. Store User Role: After successful login, store the user’s role in the frontend (e.g., using Redux, Context API, or local storage).

  2. Protect Routes: Create a higher-order component (HOC) or a custom hook to protect routes based on the user's role:

    // components/PrivateRoute.js
    import React from 'react';
    import { Route, Redirect } from 'react-router-dom';
    
    const PrivateRoute = ({ component: Component, roles, ...rest }) => (
        <Route {...rest} render={props => (
            roles.includes(user.role) ?
                <Component {...props} />
                : <Redirect to='/login' />
        )} />
    );
    
    export default PrivateRoute;
    
  3. Usage: Use the PrivateRoute component to protect routes in your application:

    import React from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import PrivateRoute from './components/PrivateRoute';
    import AdminPage from './pages/AdminPage';
    import UserPage from './pages/UserPage';
    
    const App = () => {
        return (
            <Router>
                <Switch>
                    <PrivateRoute path="/admin" roles={['admin']} component={AdminPage} />
                    <PrivateRoute path="/user" roles={['admin', 'user']} component={UserPage} />
                    <Route path="/login" component={LoginPage} />
                    <Route path="/" exact component={HomePage} />
                </Switch>
            </Router>
        );
    };
    
    export default App;
    
Published on: Jul 10, 2024, 03:07 AM  
 

Comments

Add your comment