Nestjs 具有警卫/装饰器的身份验证和角色:如何传递用户对象?

Nestjs 具有警卫/装饰器的身份验证和角色:如何传递用户对象?,nestjs,Nestjs,在警卫/装饰人员的帮助下,我尝试先检查JWT,然后检查用户的角色 我已经阅读了有关身份验证、警卫和装饰人员的文档,并理解了它们背后的原则 然而,我不能做的是以某种方式使来自JWT Guard的经过身份验证的用户可供角色Guard使用 在我找到的每一个例子中,我感兴趣的部分都被跳过/忽略了 感谢每一个提示 这是我的最新尝试: jwt.strategy.ts 角色.guard.ts users.controller.ts 您的装饰器和卫士看起来不错,但是从users.controller.ts文件的

在警卫/装饰人员的帮助下,我尝试先检查JWT,然后检查用户的角色

我已经阅读了有关身份验证、警卫和装饰人员的文档,并理解了它们背后的原则

然而,我不能做的是以某种方式使来自JWT Guard的经过身份验证的用户可供角色Guard使用

在我找到的每一个例子中,我感兴趣的部分都被跳过/忽略了

感谢每一个提示

这是我的最新尝试:

jwt.strategy.ts

角色.guard.ts

users.controller.ts


您的装饰器和卫士看起来不错,但是从users.controller.ts文件的片段来看,不清楚卫士角色是否实际应用于GET/route

然而,我确实有一个NestJS应用程序,它基于。users.controller.ts中的以下代码按预期工作:

@UseGuardsJwtAuthGuard,RoleGuard @控制器“/用户” 导出类用户控制器{ constructorprivate只读用户服务:用户服务{} @得到 @RolesUserRole.ADMIN 公共异步索引:Promise{ 返回this.userService.findAll; } // ... } 注意auth和roleguard是如何在同一范围内激活的,并且JwtAuthGuard是在RolesGuard之前添加的。如果我要更改警卫的顺序,那么RolesGuard将无法检索请求的用户


另外,您可能希望查看一段时间以前的内容,其中包含关于不同作用域中卫士顺序的一些详细信息。

您的装饰器和卫士看起来不错,但是从users.controller.ts文件的片段来看,不清楚卫士角色是否实际应用于GET/route

然而,我确实有一个NestJS应用程序,它基于。users.controller.ts中的以下代码按预期工作:

@UseGuardsJwtAuthGuard,RoleGuard @控制器“/用户” 导出类用户控制器{ constructorprivate只读用户服务:用户服务{} @得到 @RolesUserRole.ADMIN 公共异步索引:Promise{ 返回this.userService.findAll; } // ... } 注意auth和roleguard是如何在同一范围内激活的,并且JwtAuthGuard是在RolesGuard之前添加的。如果我要更改警卫的顺序,那么RolesGuard将无法检索请求的用户


此外,您可能还想看看很久以前的内容,其中包含了关于不同范围内守卫顺序的一些详细信息。

非常感谢您的帮助!经过这么多的尝试,我忘记了除了@Roles之外,你还需要RolesGuard…这真是一个不必要的错误。现在,它的工作所需-谢谢!此外,链接线程中关于导入app.module.ts的提示也很有价值,否则您将获得403。非常感谢您的帮助!经过这么多的尝试,我忘记了除了@Roles之外,你还需要RolesGuard…这真是一个不必要的错误。现在,它的工作所需-谢谢!此外,链接线程中关于导入app.module.ts的提示也很有价值,否则您总是会得到403。
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { JwtPayload } from './jwt.model';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      passReqToCallback: true,
      ignoreExpiration: false,
      secretOrKey: '0000',
      expiresIn: '3 days'
    });
  }

  async validate(payload: JwtPayload) {
    return {
      id: payload.id,
      email: payload.email,
      username: payload.username
    };
  }
}
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {
  }

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());

    if (!roles) {
      return false;
    }

    const request = context.switchToHttp().getRequest();
    const user = request.user ??? // THIS is what is missing

    return roles.some((role) => {
      return role === user.role;
    });
  }
}
import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
@UseGuards(AuthGuard('jwt'))
@Roles('admin', 'member')
@Get('/')
async doSomething(@Req() req): Promise<User> {
  return await this.usersService.doSomething(req.user.id);
}