06. Authentication & Security
1. The Vanilla Mechanics
Security in a web application involves verifying the identity of a user (Authentication) and checking their permissions (Authorization). In Express, this is usually implemented as custom middleware.
Concept: Request Interception
- Identity Verification: Checking for a JWT or session cookie in the headers.
- Permission Checks: Ensuring the user has the required roles for a specific route.
The βRawβ Implementation (Example)
const authGuard = (req, res, next) => {
const token = req.headers.authorization;
if (token === 'valid-token') {
req.user = { id: 1, role: 'admin' };
next();
} else {
res.status(401).send('Unauthorized');
}
};
const roleGuard = (role) => (req, res, next) => {
if (req.user && req.user.role === role) {
next();
} else {
res.status(403).send('Forbidden');
}
};
app.get('/admin', authGuard, roleGuard('admin'), (req, res) => {
res.send('Admin area');
});Challenges:
- Tightly Coupled: Security logic is mixed into the route definitions.
- Inconsistency: Different developers may implement security differently across the app.
- Complexity: Managing nested permissions can become complicated with plain middleware.
2. The NestJS Abstraction
NestJS uses Guards to handle authentication and authorization.
Key Advantages:
- CanActivate: Guards implement the
CanActivateinterface, making the return value (true/false) the decision maker for the request. - Metadata Access: Guards can access metadata (like required roles) defined on the route using decorators.
- DI Support: Inject other services directly into your Guards.
The NestJS Implementation:
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
@Injectable()
export class RolesGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const user = request.user;
return user && user.role === 'admin';
}
}
// In the controller:
@UseGuards(RolesGuard)
@Get('admin')
findAll() {
return 'Admin area';
}3. Engineering Labs
- Lab 6.1: Build an Express app with a custom auth middleware that validates a fake token and attaches a user object to the request.
- Lab 6.2: Re-implement the security layer in NestJS using a
Guard. Use theReflectorto read custom metadata (roles) from the route.