patterntypescriptMajor
Role-Based Access Control (RBAC) with Middleware
Viewed 0 times
rbacrolemiddlewareauthorizationroute protectionaccess control
Problem
Protecting routes by role requires duplicating authorization logic in every page component or API handler, leading to inconsistencies and missed checks.
Solution
Encode the user's role in the session/JWT. Create a centralized middleware or higher-order function that reads the role and compares it against a route-to-role map before the request reaches the handler.
Why
Centralizing authorization prevents it from being forgotten in individual handlers and makes auditing straightforward — the full permission model lives in one place.
Gotchas
- Always validate roles server-side; never trust client-side role claims from localStorage or URL params
- Roles stored in JWTs are stale until the token is refreshed — critical role changes (user banned) require session invalidation
- Keep the role set small and flat; deeply nested permission trees become unmaintainable — prefer ABAC for fine-grained rules
Code Snippets
Next.js middleware with role-based route guard
import { auth } from '@/auth';
import { NextResponse } from 'next/server';
const ROLE_ROUTES: Record<string, string[]> = {
'/admin': ['admin'],
'/dashboard': ['admin', 'user'],
};
export default auth((req) => {
const { pathname } = req.nextUrl;
const role = req.auth?.user?.role as string | undefined;
for (const [route, allowed] of Object.entries(ROLE_ROUTES)) {
if (pathname.startsWith(route)) {
if (!role || !allowed.includes(role)) {
return NextResponse.redirect(new URL('/unauthorized', req.url));
}
}
}
return NextResponse.next();
});Revisions (0)
No revisions yet.