Bird
Raised Fist0
Expressframework~20 mins

Permission middleware in Express - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Permission Middleware Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What happens when a user without permission accesses the route?

Consider this Express middleware that checks user permissions before allowing access to a route.

function checkPermission(permission) {
  return (req, res, next) => {
    if (req.user?.permissions?.includes(permission)) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}

app.get('/admin', checkPermission('admin'), (req, res) => {
  res.send('Welcome Admin');
});

What will the server respond if a user without the 'admin' permission tries to access '/admin'?

AThe server responds with status 403 and message 'Forbidden'.
BThe server responds with status 200 and message 'Welcome Admin'.
CThe server responds with status 404 because the route is not found.
DThe server crashes with a TypeError because req.user is undefined.
Attempts:
2 left
💡 Hint

Look at the middleware logic and what happens when the permission is missing.

📝 Syntax
intermediate
2:00remaining
Which middleware syntax correctly checks for multiple permissions?

You want to create middleware that allows access if the user has any of the given permissions.

Which option correctly implements this?

A
function checkAnyPermission(permissions) {
  return (req, res, next) => {
    if (permissions.find(p => req.user.permissions.includes(p))) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}
B
function checkAnyPermission(permissions) {
  return (req, res, next) => {
    if (permissions.every(p => req.user.permissions.includes(p))) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}
C
function checkAnyPermission(permissions) {
  return (req, res, next) => {
    if (req.user.permissions.includes(permissions)) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}
D
function checkAnyPermission(permissions) {
  return (req, res, next) => {
    if (permissions.some(p => req.user.permissions.includes(p))) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}
Attempts:
2 left
💡 Hint

Use an array method that returns true if at least one element matches.

🔧 Debug
advanced
2:00remaining
Why does this permission middleware cause a crash?

Look at this middleware code:

function checkPermission(permission) {
  return (req, res, next) => {
    if (req.user.permissions.includes(permission)) {
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}

Sometimes the server crashes with TypeError: Cannot read property 'includes' of undefined. Why?

ABecause <code>req.user</code> or <code>req.user.permissions</code> can be undefined if the user is not authenticated.
BBecause <code>permission</code> is not a string.
CBecause <code>next()</code> is not called properly.
DBecause <code>res.status(403).send()</code> is missing a return statement.
Attempts:
2 left
💡 Hint

Think about what happens if the user is not logged in.

state_output
advanced
2:00remaining
What is the response when middleware calls next() twice?

Consider this middleware:

function checkPermission(permission) {
  return (req, res, next) => {
    if (req.user?.permissions?.includes(permission)) {
      next();
      next();
    } else {
      res.status(403).send('Forbidden');
    }
  };
}

What happens when a user with the permission accesses the route?

AThe server sends two responses causing a network error.
BThe server responds normally with the route handler output.
CThe server throws an error because next() is called multiple times.
DThe server ignores the second next() call silently.
Attempts:
2 left
💡 Hint

Calling next() more than once in Express middleware is problematic.

🧠 Conceptual
expert
3:00remaining
How to design permission middleware for asynchronous user data loading?

You want to create permission middleware but user permissions are loaded asynchronously from a database.

Which approach correctly handles this in Express?

ALoad permissions outside middleware and store in a global variable for synchronous access.
BMake the middleware function async and use await to get permissions, then call next() or send response.
CCall next() immediately and check permissions later in the route handler.
DUse setTimeout to delay permission check inside middleware.
Attempts:
2 left
💡 Hint

Express supports async middleware functions that return promises.

Practice

(1/5)
1. What is the main purpose of permission middleware in an Express app?
easy
A. To check if a user has rights to access a route before running its handler
B. To format the response data before sending it to the client
C. To log every request made to the server
D. To handle errors thrown by route handlers

Solution

  1. Step 1: Understand middleware role

    Middleware runs before route handlers to control flow or check conditions.
  2. Step 2: Identify permission middleware function

    Permission middleware specifically checks user rights to allow or deny access.
  3. Final Answer:

    To check if a user has rights to access a route before running its handler -> Option A
  4. Quick Check:

    Permission middleware controls access = A [OK]
Hint: Permission middleware controls access before route runs [OK]
Common Mistakes:
  • Confusing permission middleware with logging middleware
  • Thinking it formats response data
  • Assuming it handles errors
2. Which of the following is the correct way to define a permission middleware function in Express?
easy
A. function checkPermission(req, res, next) { if (!req.user) next('No user'); else next(); }
B. function checkPermission(req, res) { if (!req.user) res.send('No user'); else next(); }
C. function checkPermission(req, res, next) { if (!req.user) res.send('No user'); else next(); }
D. function checkPermission(req, res, next) { if (!req.user) return; else next(); }

Solution

  1. Step 1: Check middleware signature

    Express middleware must have three parameters: req, res, next.
  2. Step 2: Verify correct usage of next()

    If permission fails, respond or send error; else call next() to continue.
  3. Final Answer:

    function checkPermission(req, res, next) { if (!req.user) res.send('No user'); else next(); } -> Option C
  4. Quick Check:

    Middleware needs (req, res, next) and calls next() [OK]
Hint: Middleware needs three params: req, res, next [OK]
Common Mistakes:
  • Missing next parameter
  • Calling next() without parentheses
  • Not sending response or calling next() properly
3. Given this middleware and route, what will be the response if req.user.role is 'guest'?
function permitAdmin(req, res, next) {
  if (req.user?.role !== 'admin') {
    return res.status(403).send('Forbidden');
  }
  next();
}

app.get('/admin', permitAdmin, (req, res) => {
  res.send('Welcome Admin');
});
medium
A. Forbidden
B. Welcome Admin
C. Internal Server Error
D. No response (timeout)

Solution

  1. Step 1: Check user role in middleware

    The middleware checks if req.user.role is not 'admin'. Here it is 'guest', so condition is true.
  2. Step 2: Middleware response on failed permission

    It sends status 403 with 'Forbidden' and does not call next(), so route handler is skipped.
  3. Final Answer:

    Forbidden -> Option A
  4. Quick Check:

    Role not admin = 403 Forbidden [OK]
Hint: If role not admin, middleware sends 403 and stops [OK]
Common Mistakes:
  • Assuming route handler runs anyway
  • Confusing status codes
  • Missing optional chaining on req.user
4. Identify the error in this permission middleware code:
function checkPermission(req, res, next) {
  if (!req.user.permissions.includes('edit')) {
    res.status(401).send('Unauthorized');
  }
  next();
}
medium
A. Middleware should not call next() at all
B. Wrong status code for unauthorized access
C. Incorrect property name 'permissions' on req.user
D. Missing return after sending response, so next() runs anyway

Solution

  1. Step 1: Analyze flow after sending response

    After res.status(401).send(), the code continues and calls next(), allowing next middleware or route to run.
  2. Step 2: Fix by adding return to stop execution

    Adding 'return' before res.status(401).send() prevents next() from running when unauthorized.
  3. Final Answer:

    Missing return after sending response, so next() runs anyway -> Option D
  4. Quick Check:

    Send response must return to stop next() [OK]
Hint: Return after res.send() to prevent next() running [OK]
Common Mistakes:
  • Not returning after sending response
  • Using wrong HTTP status code
  • Assuming next() should never be called
5. You want to create a permission middleware that allows access only if the user has at least one role from an array of allowed roles. Which code correctly implements this?
hard
A. function permitRoles(allowedRoles) { return (req, res, next) => { if (!allowedRoles.includes(req.user.role)) { res.status(403).send('Forbidden'); } next(); }; }
B. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.some(role => role === req.user.role)) { next(); } else { res.status(403).send('Forbidden'); } }; }
C. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.indexOf(req.user.role) === -1) { res.status(403).send('Forbidden'); } next(); }; }
D. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.every(role => role !== req.user.role)) { next(); } else { res.status(403).send('Forbidden'); } }; }

Solution

  1. Step 1: Understand the requirement

    Access allowed if user role matches any role in allowedRoles array.
  2. Step 2: Check each option logic

    function permitRoles(allowedRoles) { return (req, res, next) => { if (!allowedRoles.includes(req.user.role)) { res.status(403).send('Forbidden'); } next(); }; } uses includes but misses return before res.send(), so next() runs anyway. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.indexOf(req.user.role) === -1) { res.status(403).send('Forbidden'); } next(); }; } misses return before res.send(), so next() runs anyway. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.some(role => role === req.user.role)) { next(); } else { res.status(403).send('Forbidden'); } }; } uses some() to check if any role matches, then calls next() or sends 403 correctly. function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.every(role => role !== req.user.role)) { next(); } else { res.status(403).send('Forbidden'); } }; } reverses logic, allowing access if no match, which is wrong.
  3. Step 3: Choose best correct code

    function permitRoles(allowedRoles) { return (req, res, next) => { if (allowedRoles.some(role => role === req.user.role)) { next(); } else { res.status(403).send('Forbidden'); } }; } correctly implements the logic with proper flow control.
  4. Final Answer:

    Uses some() to allow access if any role matches, else sends 403 -> Option B
  5. Quick Check:

    Use some() to check roles and control flow correctly [OK]
Hint: Use some() to check if user role is in allowed roles [OK]
Common Mistakes:
  • Not returning after sending response
  • Using every() incorrectly
  • Calling next() even after forbidden response