当前位置: 首页 > 工具软件 > nestjs-bff > 使用案例 >

Nestjs中的守卫

费学
2023-12-01

NestJs中的守卫(guards)概念

  • 文档:https://docs.nestjs.com/guards
  • 守卫是一个使用 @Injectable()装饰器装饰的类,并且实现了CanActivate接口
  • 是一个类似于中间件的类,以前在KOA和EGG中,我们的权限判断都是在中间件中处理的
  • 其实中间件是比较笨拙的,它并不知道调用next()后会执行哪些处理程序
  • 在Nestjs中提供了守卫来作为一项主要职能,去确定请求是否应该由当前路由处理程序处理
  • 守卫可以访问 ExecutionContext 对象,依次可以知道确切要执行什么
  • 当然,如果用中间件来处理的时候也可以完成

创建和使用守卫

  • $ nest g guard auth
    // src/guard/auth.guard.ts
    import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
        canActivate(
            context: ExecutionContext,
        ): boolean | Promise<boolean> | Observable<boolean> {
            // 在这里可以写一些你要的代码 TODO
            return true; // 注意这里 true 和 false
        }
    }
    
  • 在上述代码中,如果返回true,则可以访问程序,如果false则无法访问
  • 创建好守卫后,可以全局配置,可以在模块中配置

1 ) 下面我们在 admin模块的 user 控制器中使用守卫

import { Controller, Get, UseGuards } from '@nestjs/common';
import { UserService } from '../../service/user/user.service'
import { AppService  } from 'src/app.service';
import { BaseService } from 'src/module/common/service/base/base.service';
import { AuthGuard } from 'src/guard/auth.guard';

@Controller('admin/user')
// @UseGuards(AuthGuard) // 在这里写说明整个控制器会被控制
export class UserController {
    constructor(
        private userService:UserService,
        private appService:AppService,
        private baseService:BaseService,
    ) {}

    @Get()
    index() {
        const list = this.userService.getUser()
        console.log('list', list)
        console.log(this.appService.getHello())
        console.log(this.baseService.getList())
        return '我是admin模块里的user控制器';
    }

    @Get('add')
    add() {
        return '我是admin模块里的user/add控制器';
    }

    @Get('edit')
    @UseGuards(AuthGuard) // 在这里写只会控制这个方法、
    edit() {
        return '我是admin模块里的user/edit控制器';
    }
}
  • 从上面代码中可以看到,可以在全部控制器中使用,也可以在控制器中某个方法使用

2 ) 全局使用守卫

  • 在根模块中配置

    import { Module } from '@nestjs/common';
    import { APP_GUARD } from '@nestjs/core';
    
    @Module({
      providers: [
        {
          provide: APP_GUARD,
          useClass: RolesGuard,
        },
      ],
    })
    export class AppModule {}
    
  • 在main.ts中配置

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { AuthGuard } from 'src/guard/auth.guard';
    
    async function bootstrap() {
        const app = await NestFactory.create(AppModule);
    	app.useGlobalGuards(new AuthGuard()) // 全局守卫配置
    	await app.listen(3000);
    }
    bootstrap();
    

在守卫中基于Session实现基于用户权限判断

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const req = context.switchToHttp().getRequest() // 这个就相当于中间件中的request
    console.log(req) 
    // TODO 你想要做的事情
    return true;
  }
}
 类似资料: