DocsSection 4
4Section 4 of 10
Authentication Deep Dive
Authentication Deep Dive
4.1 The Auth Flow
User submits login form
↓
POST /api/auth/login
↓
Verify credentials (bcrypt.compare)
↓
Create session (Redis or memory)
↓
Set session cookie (HTTP-only, Secure)
↓
Redirect to role-based route
4.2 Session Storage
Two modes:
-
Redis (production):
- Sessions stored in Redis
- Survives server restarts
- Shared across multiple servers
-
In-Memory (fallback):
- Sessions in Node.js Map
- Lost on restart
- Single server only
Session structure:
interface Session {
token: string; // Random UUID
userId: string; // User ID
role: 'admin' | 'sales' | 'client';
email: string;
createdAt: number;
lastAccessedAt: number;
}
4.3 Middleware Protection
File: middleware.ts (runs on EVERY request)
export function middleware(request: NextRequest) {
const path = request.nextUrl.pathname;
// 1. Check if route requires auth
if (isPublicRoute(path)) {
return NextResponse.next(); // Allow through
}
// 2. Check session cookie
const session = request.cookies.get('session');
if (!session) {
return redirectToLogin(path); // Kick to login
}
// 3. Add role header for downstream checks
const response = NextResponse.next();
response.headers.set('x-required-role', getRequiredRole(path));
return response;
}
4.4 Role-Based Access
Three roles:
| Role | Can Access | Cannot Access |
|---|---|---|
| admin | Everything | Nothing blocked |
| sales | /sales/*, /dashboard | /admin/*, /api/deploy |
| client | /dashboard, /settings | /admin/, /sales/ |
Enforced at multiple levels:
- Middleware: Route-level blocking
- API routes: Function-level checks
- UI: Hide buttons/links based on role