首页 > 解决方案 > 在装饰器中设置变量值

问题描述

我目前正在将索赔系统开发到我的 CMS 中,并且我为每个创建的实体都有一个通用控制器(和服务)。问题是我想将声明系统集成到我的通用控制器中,但为此我需要将 @SetMetadata 装饰器设置到创建的所有通用路由中。

我试图在我的通用控制器的 @SetMetadata 装饰器中插入一个变量,但我收到了这个警告:

S2532: Object is possibly 'undefined'.

我在上面放了一个 tsignore,但元数据中设置的值要么未设置,要么未定义,因为在我的 jwtGuard 类中我无法找到它。

我的通用控制器如下所示:


export class ProtectedRestController<T extends RestEntity> {
  private readonly claimType: string;
  constructor(private readonly restService: IRestService<T>, claimType: string) {
    
    this.claimType = claimType;
  }

//THIS IS NOT WORKING
  // @ts-ignore
  @SetMetadata(this.claimType, 'edit')
  @UseGuards(JwtGuard)
  @Get(':page/:items')
  protected async findAllPaginate(
    @Param('page') page: number,
    @Param('items') items: number,
  ): Promise<T[]> {
    return this.restService.getAllPaginate(page, items);
  }
....

我的策略是将例如“事件”作为声明类型,用户必须拥有至少为“编辑”值的声明“事件”,我可以在我的 JWTGuard 类中控制它。

这确实适用于非通用类(我已经测试过了)。

这是我的 JWTGuard 类:


@Injectable()
export class JwtGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  public canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    if (!this.checkClaims(context)) {
      return false;
    }

    return super.canActivate(context);
  }

  // Used to throw a custom error
  // THIS FUNCTION IS NOT UNUSED!!!
  public handleRequest(err: any, user: any, info: any): any {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw new HttpException('Token Expired', HttpStatus.SEE_OTHER);
    }
    return user;
  }

  private checkClaims(context: ExecutionContext): boolean {
    const decodedToken = jwt_decode(context.switchToHttp().getRequest().headers.authorization);

    let canAccess = true;

    for (const defaultClaim of defaultClaims) {
      const valueOfTypeNeeded = this.reflector.getAllAndOverride<string>(defaultClaim.type, [
        context.getHandler(),
        context.getClass(),
      ]);

      if (valueOfTypeNeeded !== undefined) {
        console.log(valueOfTypeNeeded);
        // @ts-ignore
        const claim = decodedToken.claims.find((claimToSearch) => claimToSearch.type === defaultClaim.type);
        if (claim) {
          if (claim.value.toString() === 'none') {
            canAccess = false;
            break;
          }
          if (claim.value.toString() === 'edit' && valueOfTypeNeeded.toString() === 'delete') {
            canAccess = false;
            break;
          }
        }
      }
    }
    return canAccess;
  }
}

有人知道这个问题的解决方案吗?

标签: javascriptnode.jstypescriptjwtnestjs

解决方案


推荐阅读