Nest.js - 守卫

2020-07-13  本文已影响0人  stevekeol
概念

顾名思义,守卫根据运行时出现的某些条件(权限,角色,访问控制列表等)来确定给定的请求是否交给对应的路由处理程序。

授权守卫

经过身份验证的请求(请求头附加了token),授权守卫将提取和验证token,并使用提取的信息来确认请求是否可以继续。

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

@Injectable()
export class AuthGuard implements CanActive {
  canActive(
    context: ExecutionContext
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
执行上下文
export interface ExecutionContext extends ArgumentsHost {
  getClass<T = any>(): Type<T>;
  getHandler(): Function;
}
角色认证
//允许所有请求继续
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}

绑定守卫

@Controller('cats')
//@UseGuards(new RolesGuard())
@UseGuards(RolesGuard)  //控制器范围的守卫
export class CatsController {}
反射器

根据执行上下文为不同的路由提供不同的权限方案;
Nest使用@SetMetadata()装饰器将定制元数据附加到路由处理程序,守卫根据提供的角色数据,做出决策。

//roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
//cats.controller.ts
@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
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 roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
上一篇 下一篇

猜你喜欢

热点阅读