Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express middleware: allow access to only admin or moderator

I want a route to be only accessible by moderator or admin. I tried to apply a middleware of array on the route. But, it just denies access if one middleware fails to apply.

so, say I am admin or moderator I can access to /store-detail.

But here, If I am admin I can not access it because it check for moderator as well.

Here both middlewares admin and moderator is being applied.

I want it to apply admin or moderator.
How can I make just one of them to be applied?
So that only admin or moderator can access it.
verify middleware is to verify jwt token.
router

router.post('/store-detail', [verify, admin, moderator], async (req, res) => {
    //validate data
}}

middlewares

const User = require('../models').User

module.exports = async function (req, res, next) { 
    // 401 Unauthorized
    const user = await User.findOne({ where: { id : req.user.id}})
    if(user.role !== 'moderator') return res.status(403).send({error: { status:403, message:'Access denied.'}});
    next();
  }
const User = require('../models').User

module.exports = async function (req, res, next) { 
    // 401 Unauthorized
    const user = await User.findOne({ where: { id : req.user.id}})
    if(user.role !== 'admin') return res.status(403).send({error: { status:403, message:'Access denied.'}});
    next();
  }
like image 726
8bitIcon Avatar asked Sep 14 '25 17:09

8bitIcon


1 Answers

Middlewares are executed successively, so the first middleware that denies access, sends an error. I suggest to create a single middleware that accepts a parameter:

module.exports = function hasRole(roles) {
  return async function(req, res, next) {
    const user = await User.findOne({ where: { id: req.user.id } });
    if (!user || !roles.includes(user.role)) {
      return res.status(403).send({error: { status:403, message:'Access denied.'}});
    }
    next();
  }
}

And use the middleware like this:

router.post('/store-detail', verify, hasRole(['admin', 'moderator']), async (req, res) => {})
like image 109
Jérémie L Avatar answered Sep 16 '25 14:09

Jérémie L