簡體   English   中英

Nestjs Roles Decorator:讓用戶脫離有效負載數據的瘋狂行為

[英]Nestjs Roles Decorator: Crazy behaviour with getting user out of payload data

我只是想在 Nestjs 中實現我的角色裝飾器。 到目前為止一切順利,直到我想將來自 jwt-token 的有效負載數據的用戶與所需的角色進行比較。 我無法解釋這是怎么可能的,但只有讓 function 返回始終為真,才能從有效負載數據中獲取用戶和角色。 在我設置條件后,用戶未定義。 這怎么可能?

這是我的(縮短的)用戶 controller,我在其中使用裝飾器:

    @UseGuards(JwtAuthGuard, RolesGuard)
@Controller('users')
export class UsersController {
  constructor(private readonly userService: UserService) {}
  private readonly logger = new Logger(LoggingService.name);

  @Post('/create')
  async create(@Body() createUserDto: CreateUserDto) {
    const hashedPassword = await bcrypt.hash(createUserDto.password, 10);
    createUserDto.password = hashedPassword
    return this.userService.createUser(createUserDto);
  }

  @Roles(Role.SUPERADMIN)
  @Get('/')
  showUsers() {
    return this.userService.getUsers();
  }

這是角色裝飾器,有條件:

import { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { LoggingService } from 'src/services/logging/logging.service';
import { User } from 'src/user/schemas/user.schema';
import { Role } from '../role.enum';
import { ROLES_KEY } from '../decorators/roles.decorator';
import { Types } from 'mongoose';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}
  private readonly logger = new Logger(LoggingService.name);

    canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {

        const roles = this.reflector.get<Role[]>(ROLES_KEY, context.getHandler());
        // If there is no Roles-Decorator, just pass through
        if (!roles) {
          return true;
        }

        this.logger.debug("REQUIRED ROLES: ", roles)
        

        const request = context.switchToHttp().getRequest();
        const userRole = request.user?.roles;
        const userID = request.user?.sub;
        this.logger.debug("ROLES GUARD USER", userID);
        this.logger.debug("USER ROLE", userRole);


        // Else, check the request header if it matches

        if (roles.includes(userRole)) {
            return true;
        } else { return false }

  }

}

記錄 output (當我嘗試訪問路由時):

[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] REQUIRED ROLES: 
[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] superadmin
[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] ROLES GUARD USER
[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] undefined
[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] USER ROLE
[Nest] 4460  - 25.11.2021, 18:56:33   DEBUG [LoggingService] undefined

但是當我這樣做時:

// Else, check the request header if it matches

        // if (roles.includes(userRole)) {
        //     return true;
        // } else { return false }

        return true;

日志記錄 output 是這樣的:

[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] REQUIRED ROLES: 
[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] superadmin
[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] ROLES GUARD USER
[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] 619962ad86e412dc06983a0e
[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] USER ROLE
[Nest] 39888  - 25.11.2021, 19:00:14   DEBUG [LoggingService] superadmin

控制流是從上到下的,對吧? 任何幫助將不勝感激!

在應用程序注冊的任何模塊中使用APP_GUARD守衛注冊為全局守衛,它將在每個請求之前運行。 我要做的是注冊兩個全局警衛,一個用於JwtAuthGuard一個用於RolesGuard ,並實現一個@JwtSkip()裝飾器,它告訴JwtAuthGuard它可以跳過此路由上的身份驗證(對於RolesGuard與它相同不應該有任何與之相關的角色

我找到了解決方案!

我沒有在全局上下文中注冊 RolesGuard。 所以我繼續說

app.useGlobalGuards(new RolesGuard(new Reflector()));

在 main.ts 中。 然后它突然起作用了。 我修改了通過 Guard 的條件,如下所示:

// Else, check the request header if it matches

        if (roles.some(r => r == userRole)) {
            this.logger.log("ROLES GUARD: PASS")
            return true;
        } else { 
          this.logger.error("ROLES GUARD: DENIED")
          return false 
        }

希望這對任何人都有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM