Discover how a simple middleware can save your app from security leaks and messy code!
Admin vs user route protection in Express - When to Use Which
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine building a website where some pages are only for admins and others for regular users. You try to check user roles on every page manually by writing repeated code everywhere.
Manually checking roles on every route is tiring and easy to forget. If you miss a check, unauthorized users might see sensitive info. It also makes your code messy and hard to update.
Using route protection middleware lets you centralize role checks. You write the check once, then apply it to routes needing admin or user access. This keeps your code clean and secure.
app.get('/admin', (req, res) => { if (req.user.role !== 'admin') { return res.status(403).send('Forbidden'); } res.send('Welcome Admin'); });
function checkRole(role) {
return (req, res, next) => {
if (req.user.role !== role) return res.status(403).send('Forbidden');
next();
};
}
app.get('/admin', checkRole('admin'), (req, res) => {
res.send('Welcome Admin');
});This approach makes it easy to protect many routes by role, improving security and keeping your code simple and reusable.
On a company dashboard, only HR staff can access employee salary info, while regular employees see their own profiles. Route protection middleware enforces this smoothly.
Manual role checks are repetitive and risky.
Middleware centralizes and simplifies access control.
Secure your app while keeping code clean and maintainable.
Practice
Solution
Step 1: Understand middleware role
Middleware runs before route handlers and can check conditions like user roles.Step 2: Role-based access control
Middleware can allow access only if the user has the right role, such as admin or user.Final Answer:
To check user roles and allow or deny access accordingly -> Option AQuick Check:
Middleware controls access = D [OK]
- Thinking middleware speeds up server
- Confusing middleware with logging only
- Believing middleware changes URLs
Solution
Step 1: Understand middleware placement
Middleware should be passed as a second argument before the route handler function.Step 2: Check syntax correctness
app.get('/admin', adminMiddleware, (req, res) => { res.send('Admin page'); }); correctly places adminMiddleware between route path and handler.Final Answer:
app.get('/admin', adminMiddleware, (req, res) => { res.send('Admin page'); }); -> Option BQuick Check:
Middleware before handler = A [OK]
- Calling middleware inside handler instead of passing it
- Using middleware after sending response
- Passing middleware as a function call instead of reference
function adminMiddleware(req, res, next) {
if (req.user.role === 'admin') next();
else res.status(403).send('Access denied');
}
app.get('/admin', adminMiddleware, (req, res) => {
res.send('Welcome Admin');
});Solution
Step 1: Analyze middleware condition
The middleware checks if req.user.role is 'admin'. If not, it sends 403 with 'Access denied'.Step 2: User role is 'user'
Since role is 'user', the else branch runs, sending 403 and 'Access denied'.Final Answer:
'Access denied' with status 403 -> Option AQuick Check:
Non-admin blocked with 403 = A [OK]
- Assuming next() always runs
- Ignoring status code sent by middleware
- Thinking response is 'Welcome Admin' for all roles
function adminMiddleware(req, res, next) {
if (req.user.role === 'admin') next();
else res.send('Access denied');
}
app.get('/admin', adminMiddleware, (req, res) => {
res.send('Admin area');
});Solution
Step 1: Check middleware response
When denying access, middleware sends a message but does not set HTTP status code.Step 2: Importance of status code
Without status 403, client gets status 200 which is misleading for access denial.Final Answer:
Missing status code when sending 'Access denied' -> Option CQuick Check:
Send 403 on denial = C [OK]
- Not setting status code on error
- Calling next() after sending response
- Placing middleware after route handler
function authMiddleware(req, res, next) {
if (req.user) next();
else res.status(401).send('Login required');
}
function adminMiddleware(req, res, next) {
if (req.user?.role === 'admin') next();
else res.status(403).send('Admin only');
}
// Which setup is correct?Solution
Step 1: Understand middleware order
For '/admin', user must be logged in (authMiddleware) and have admin role (adminMiddleware).Step 2: Apply correct middleware per route
'/profile' only needs authMiddleware to check login. app.get('/admin', authMiddleware, adminMiddleware, (req, res) => res.send('Admin')); app.get('/profile', authMiddleware, (req, res) => res.send('Profile')); applies both correctly in order.Final Answer:
app.get('/admin', authMiddleware, adminMiddleware, (req, res) => res.send('Admin')); app.get('/profile', authMiddleware, (req, res) => res.send('Profile')); -> Option DQuick Check:
Auth then admin for admin route = B [OK]
- Reversing middleware order
- Using adminMiddleware alone for profile
- Not protecting admin route with authMiddleware
