Not everyone gets in
Some routes need an API key; some are for managers only. A guard is a class with canActivate(context): return true to let the request through, or throw (401/403) to stop it — before the handler runs.
CanActivate and @UseGuards
import { Controller, Get, Injectable, UnauthorizedException, UseGuards } from "@nestjs/common";
@Injectable()
export class ApiKeyGuard {
canActivate(context: any) {
const req = context.switchToHttp().getRequest();
if (req.headers["x-api-key"] !== "cafe-secret") throw new UnauthorizedException("Missing or invalid API key");
return true;
}
}
@Controller("reports")
@UseGuards(ApiKeyGuard)
export class ReportsController {
@Get("sales")
sales() {
return { today: 24500 };
}
}- Guards are injectable — they can use services (e.g. a sessions service).
- Roles: tag routes with SetMetadata("roles", ["manager"]) and read it in the guard with Reflector.
- Real auth: @nestjs/passport + JWT strategies plug into guards the same way.