RBAC cho phép kiểm soát quyền truy cập dựa trên role của user. Pattern chuẩn:
Bước 1: tạo @Roles() decorator:
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);Bước 2: tạo RolesGuard:
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(ctx: ExecutionContext): boolean {
const required = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
ctx.getHandler(), ctx.getClass(),
]);
if (!required) return true; // No roles required
const { user } = ctx.switchToHttp().getRequest();
return required.some(role => user.roles?.includes(role));
}
}Bước 3: đăng ký global và dùng:
@Roles(Role.ADMIN)
@Get('admin-only')
getAdminData() { ... }Ngoài roles, có thể implement Permission-based (fine-grained) với casl library: ability.can(Action.Update, 'User').
Lưu ý: guard chạy sau JWT guard — đảm bảo user object đã được attach vào request trước khi roles guard chạy.
RBAC controls access based on user roles. Standard pattern:
Step 1: create @Roles() decorator:
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);Step 2: create RolesGuard reading metadata via Reflector, checking user.roles.
Step 3: register globally and apply:
@Roles(Role.ADMIN)
@Get('admin-only')
getAdminData() { ... }For fine-grained permissions use the casl library.
Pitfall: RolesGuard runs after JwtGuard — ensure user is already attached to request.