Jwt 策略后 ExecutionContext 中缺少用户 [英] User missing in ExecutionContext after Jwt strategy

查看:11
本文介绍了Jwt 策略后 ExecutionContext 中缺少用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我已经实现了 jwt 守卫,它工作得很好,使用 Passport,jwt 正在验证颁发的令牌,我可以通过 @Request 通过 req.user 查看用户,在将基于角色的身份验证作为插件实现后出现问题jwt 已经在工作的守卫了.

Currently I have implemented jwt guard which is working just fine, using Passport, jwt is validating issued tokens and I can pass @Request to see the user via req.user, issue come up after implementing Role based authentication as an addon to the already working guard of jwt.

我遵循了 nestjs.com 上提供的指导,但没有帮助.https://docs.nestjs.com/guards

I followed guidance provided at nestjs.com, however it did not help. https://docs.nestjs.com/guards

基本角色配置:

roles.decorator.ts

roles.decorator.ts

import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

roles.guard.ts

roles.guard.ts

import { Injectable, CanActivate, ExecutionContext } 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 true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    console.log(user);
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}

RolesGuard 通过以下方式注入到 app.module.ts 内容中:

The RolesGuard is Injected in app.module.ts content via:

providers: [{
    provide: APP_GUARD,
    useClass: RolesGuard,
  }]

用于验证的控制器标头:

My controller header for verification:

  @UseGuards(AuthGuard('jwt'))
  @Roles('admin')
  @Get('admin')
  async admin(@Request() req) {
    return this.authService.me(req.user);
  }

它应该检查用户是否提供了承载令牌并且它是活动的,jwt 还将用户分配给请求用户,我可以使用 @Request() req 然后 req.user 检索,但是当涉及到 @Roles('admin') 时,它在 roles.guard.ts 中返回 undefined在console.log(user)"部分最后,不允许用户查看给定的资源,似乎 RoleGuardAuthGuard('jwt'),但是请求中包含 Brearer 令牌,因此应将其转换为用户.

It should check if user provided Bearer token and it is active, jwt will also assign user to Request user, which I can retrieve using @Request() req and then req.user, however when it comes to @Roles('admin'), it returns undefined in roles.guard.ts In section "console.log(user)" so at the end, user is not allowed to see given resource, it seems like RoleGuard is Injected before AuthGuard('jwt'), however the request has Brearer token inside so it should be converted to user.

我正在考虑改变我的 jwt 策略并在那里实现 CanActivate 接口并在那里编写它,但这对我来说听起来不是一个好的解决方案,因为我想让它们分开.

I was thinking to change my jwt strategy and implement there CanActivate interface and write it there, but it doesn't sound like good solution to me as I want to keep them separate.

推荐答案

我可以为你确认 RoleGuardAuthGuard 之前作为 被调用RoleGuard 是全局范围内的应用程序(在您定义它的位置),而 AuthGuard 是本地范围内的函数.如果您不介意将 RoleGuard 设置为全局范围,而是针对每个方法设置范围,即使要编写更多代码,您也可以将其添加到 @UseGuards装饰师.除此之外,就像你说的,你可以将两个守卫合二为一,但这可能会变得混乱和笨拙.

I can confirm for you that the RoleGuard is being called before the AuthGuard as the RoleGuard is globally scoped to the application (with where you have it defined) and the AuthGuard is locally scoped to the function. If you don't mind not having the RoleGuard globally scoped and instead scoped against each method, even though it is more code to write, you can add it to the @UseGuards decorator. Other than that, like you said, you could merge the two guards into one, but that could get messy and unwieldy.

这篇关于Jwt 策略后 ExecutionContext 中缺少用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆