NestJS认证授权实践
如何在NestJS中实现基于JWT的身份认证和角色授权?有没有完整的代码示例可以参考?
使用Passport和JWT做认证时,如何正确配置策略和守卫?
想请教NestJS中处理权限控制的常见方案,比如RBAC或ACL,哪种更适合中小型项目?
在微服务架构下,认证授权模块该如何设计才能保证安全性和可扩展性?
遇到token刷新和黑名单管理的问题,有什么成熟的NestJS解决方案吗?
在NestJS中实现认证和授权可以分为几个步骤:
-
安装必要的依赖:首先,你需要安装
[@nestjs](/user/nestjs)/passport
、passport
、[@nestjs](/user/nestjs)/jwt
等模块。例如:npm install [@nestjs](/user/nestjs)/passport passport [@nestjs](/user/nestjs)/jwt jsonwebtoken
-
配置Passport:创建一个策略类来处理认证逻辑。例如,使用JWT策略:
import { Strategy } from 'passport-jwt'; import { PassportStrategy } from '[@nestjs](/user/nestjs)/passport'; import { Injectable, UnauthorizedException } from '[@nestjs](/user/nestjs)/common'; [@Injectable](/user/Injectable)() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ secretOrKey: 'your-secret-key', }); } async validate(payload: any) { const user = await this.findUserById(payload.sub); if (!user) throw new UnauthorizedException(); return user; } }
-
创建认证控制器:使用
@UseGuards()
装饰器来保护路由。import { Controller, Post, Body, UseGuards } from '[@nestjs](/user/nestjs)/common'; import { AuthService } from './auth.service'; import { AuthGuard } from '[@nestjs](/user/nestjs)/passport'; [@Controller](/user/Controller)('auth') export class AuthController { constructor(private authService: AuthService) {} @Post('login') async login(@Body() user: any) { return this.authService.login(user); } @Post('protected') @UseGuards(AuthGuard('jwt')) protectedRoute() { return { message: 'This is a protected route' }; } }
-
配置JWT模块:在
AppModule
中配置JWT模块。import { Module } from '[@nestjs](/user/nestjs)/common'; import { JwtModule } from '[@nestjs](/user/nestjs)/jwt'; [@Module](/user/Module)({ imports: [ JwtModule.register({ secret: 'your-secret-key', signOptions: { expiresIn: '60s' }, }), ], }) export class AppModule {}
通过这些步骤,你就可以在NestJS应用中实现基本的认证和授权功能。记得根据实际需求调整策略和配置。
在NestJS中实现认证授权,首先使用@nestjs/passport
结合passport
库实现认证,常用JWT或本地策略。例如:
- 安装依赖:
npm install @nestjs/passport passport passport-jwtjsonwebtoken
- 创建
AuthModule
,配置Passport模块。 - 使用
@Injectable()
的AuthService
生成JWT令牌。 - 创建
JwtStrategy
处理JWT验证。 - 在控制器方法上使用
@UseGuards(AuthGuard('jwt'))
添加保护。
对于授权,可以利用@nestjs/authorization
或自定义逻辑:
- 定义角色(如admin/user)。
- 在服务或守卫中检查用户角色是否符合要求。
- 使用装饰器如
@Roles('admin')
与自定义Guard结合。
例如:
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) return true;
const request = context.switchToHttp().getRequest();
return matchUserRole(request.user.role, roles);
}
}
最后,在需要的角色方法上标记@SetMetadata('roles', ['admin'])
。
NestJS 认证授权实践指南
NestJS 提供了完善的认证和授权机制,主要通过以下模块实现:
1. 基础认证方案
JWT 认证实现
// auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
JwtModule.register({
secret: 'your-secret-key',
signOptions: { expiresIn: '60s' },
}),
],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
// jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: 'your-secret-key',
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
2. 基于角色的授权 (RBAC)
// roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
// roles.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.get<string[]>(
'roles',
context.getHandler(),
);
if (!requiredRoles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return requiredRoles.some((role) => user.roles?.includes(role));
}
}
3. 控制器中使用
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
import { JwtAuthGuard } from './jwt-auth.guard';
@Controller('profile')
@UseGuards(JwtAuthGuard, RolesGuard)
export class ProfileController {
@Get()
@Roles('admin')
getProfile() {
return 'Admin profile';
}
}
4. 进阶实践
- 使用环境变量配置密钥:通过
ConfigModule
管理敏感信息 - 刷新令牌机制:实现长期会话
- 多因素认证:增强安全性
- 权限管理系统:实现更细粒度的权限控制
NestJS 的认证授权体系灵活且强大,可以根据项目需求选择 Passport 策略或自定义方案。