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
Permission middleware
📖 Scenario: You are building a simple Express server that controls access to certain routes based on user roles.Users have roles like 'admin' or 'user'. You want to create a middleware function that checks if the user has permission to access a route.
🎯 Goal: Create a permission middleware function that checks if the logged-in user has the required role to access a route. Then apply this middleware to protect a route.
📋 What You'll Learn
Create an Express app with a sample user object
Define a required role variable for permission checking
Write a middleware function called checkPermission that checks the user's role
Use the checkPermission middleware on a protected route
💡 Why This Matters
🌍 Real World
Permission middleware is used in web servers to control access to routes based on user roles or permissions, ensuring security and proper authorization.
💼 Career
Understanding middleware and permission checks is essential for backend developers working with Express or similar frameworks to build secure APIs.
Progress0 / 4 steps
1
Create a sample user object
Create a variable called user that is an object with these exact properties: name set to 'Alice' and role set to 'user'.
Express
Hint
Use const user = { name: 'Alice', role: 'user' };
2
Define the required role variable
Create a variable called requiredRole and set it to the string 'admin'.
Express
Hint
Use const requiredRole = 'admin';
3
Write the permission middleware function
Write a middleware function called checkPermission that takes req, res, and next as parameters. Inside it, check if user.role is equal to requiredRole. If yes, call next(). Otherwise, respond with status 403 and JSON message { error: 'Access denied' }.
Express
Hint
Check the user's role and call next() if allowed, else send a 403 response.
4
Use the middleware on a protected route
Create an Express app by requiring express and calling express(). Then create a GET route at '/admin' that uses the checkPermission middleware. The route handler should respond with JSON { message: 'Welcome admin' }.
Express
Hint
Use app.get('/admin', checkPermission, (req, res) => { ... }) to protect the route.
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
Step 1: Understand middleware role
Middleware runs before route handlers to control flow or check conditions.
Step 2: Identify permission middleware function
Permission middleware specifically checks user rights to allow or deny access.
Final Answer:
To check if a user has rights to access a route before running its handler -> Option A
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
Step 1: Check middleware signature
Express middleware must have three parameters: req, res, next.
Step 2: Verify correct usage of next()
If permission fails, respond or send error; else call next() to continue.
Final Answer:
function checkPermission(req, res, next) { if (!req.user) res.send('No user'); else next(); } -> Option C
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'?
The middleware checks if req.user.role is not 'admin'. Here it is 'guest', so condition is true.
Step 2: Middleware response on failed permission
It sends status 403 with 'Forbidden' and does not call next(), so route handler is skipped.
Final Answer:
Forbidden -> Option A
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
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.
Step 2: Fix by adding return to stop execution
Adding 'return' before res.status(401).send() prevents next() from running when unauthorized.
Final Answer:
Missing return after sending response, so next() runs anyway -> Option D
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
Step 1: Understand the requirement
Access allowed if user role matches any role in allowedRoles array.
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.
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.
Final Answer:
Uses some() to allow access if any role matches, else sends 403 -> Option B
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]