NestJS认证授权实践

如何在NestJS中实现基于JWT的身份认证和角色授权?有没有完整的代码示例可以参考?

使用Passport和JWT做认证时,如何正确配置策略和守卫?

想请教NestJS中处理权限控制的常见方案,比如RBAC或ACL,哪种更适合中小型项目?

在微服务架构下,认证授权模块该如何设计才能保证安全性和可扩展性?

遇到token刷新和黑名单管理的问题,有什么成熟的NestJS解决方案吗?

3 回复

在NestJS中实现认证和授权可以分为几个步骤:

  1. 安装必要的依赖:首先,你需要安装[@nestjs](/user/nestjs)/passportpassport[@nestjs](/user/nestjs)/jwt等模块。例如:

    npm install [@nestjs](/user/nestjs)/passport passport [@nestjs](/user/nestjs)/jwt jsonwebtoken
    
  2. 配置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;
        }
    }
    
  3. 创建认证控制器:使用@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' };
        }
    }
    
  4. 配置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或本地策略。例如:

  1. 安装依赖:npm install @nestjs/passport passport passport-jwtjsonwebtoken
  2. 创建AuthModule,配置Passport模块。
  3. 使用@Injectable()AuthService生成JWT令牌。
  4. 创建JwtStrategy处理JWT验证。
  5. 在控制器方法上使用@UseGuards(AuthGuard('jwt'))添加保护。

对于授权,可以利用@nestjs/authorization或自定义逻辑:

  1. 定义角色(如admin/user)。
  2. 在服务或守卫中检查用户角色是否符合要求。
  3. 使用装饰器如@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. 进阶实践

  1. 使用环境变量配置密钥:通过 ConfigModule 管理敏感信息
  2. 刷新令牌机制:实现长期会话
  3. 多因素认证:增强安全性
  4. 权限管理系统:实现更细粒度的权限控制

NestJS 的认证授权体系灵活且强大,可以根据项目需求选择 Passport 策略或自定义方案。

回到顶部