NestJS:使用 JWT 将验证选项添加到 AuthGuard

2024-05-27

我正在尝试利用AuthGuard装饰器和护照 JWT 策略,遵循文档 https://docs.nestjs.com/techniques/authentication.

文档中的所有内容都运行良好。但我现在想保护 JWT 中包含的范围的路由。这是我的应用程序生成的基本 jwt 有效负载:

{
  "user": {
    "id": "20189c4f-1183-4216-8b48-333ddb825de8",
    "username": "[email protected] /cdn-cgi/l/email-protection"
  },
  "scope": [
    "manage_server"
  ],
  "iat": 1534766258,
  "exp": 1534771258,
  "iss": "15f2463d-8810-44f9-a908-801872ded159",
  "sub": "20189c4f-1183-4216-8b48-333ddb825de8",
  "jti": "078047bc-fc1f-4c35-8abe-72834f7bcc44"
}

这是基本的保护路线,由AuthGuard装饰器:

@Get('protected')
@UseGuards(AuthGuard('jwt'))
async protected(): Promise<string> {
    return 'Hello Protected World';
}

我想添加选项并将该路线的访问限制为具有以下权限的人manager_server范围进入他们的 JWT。所以在阅读了一些内容之后AuthGuard代码,我认为我能够编写如下内容:

@Get('protected')
@UseGuards(AuthGuard('jwt', {
    scope: 'manage_server'
}))
async protected(): Promise<string> {
    return 'Hello Protected World';
}

但是,我在文档中看不到可以使用此选项的位置。

我认为添加一个选项参数validate的功能JWTStrategy可以成功,但事实并非如此。这是我的validate函数(包含在jwt.strategy.ts file):

async validate(payload: JwtPayload, done: ((err: any, value: any) => void)) {
    const user = await this.authService.validateUser(payload);
    if (!user) {
        return done(new UnauthorizedException(), false);
    }
    done(null, user);
}

非常感谢您的帮助,如果您需要,请随时在评论中向我询问更多信息。


当你看着code https://github.com/nestjs/passport/blob/a69279e2a001cd872b9e652b7075e068518bac8d/lib/auth.guard.tsAuthGuard 的,看起来像options.callback功能是唯一可能的定制。

我认为而不是自己写AuthGuard支持范围检查,有一个更干净ScopesGuard (or RolesGuard)有自己的装饰器,比如@Scopes('manage_server')反而。为此,您只需按照RolesGuard中的示例docs https://docs.nestjs.com/guards,它也只是检查 JWT 负载下的属性user请求中的属性。


基本步骤

创建一个@Scopes()装饰器:

export const Scopes = (...scopes: string[]) => SetMetadata('scopes', scopes);

创建一个ScopesGuard:

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

  canActivate(context: ExecutionContext): boolean {
    const scopes = this.reflector.get<string[]>('scopes', context.getHandler());
    if (!scopes) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const hasScope = () => user.scopes.some((scope) => scopes.includes(scope));
    return user && user.scopes && hasScope();
  }
}

使用 ScopesGuard 作为所有路由的全局防护(当没有给出范围时返回 true):

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: ScopesGuard,
    },
  ],
})
export class ApplicationModule {}

然后在端点上使用它:

@Get('protected')
@UseGuards(AuthGuard('jwt'))
@Scopes('manage_server')
async protected(): Promise<string> {
    return 'Hello Protected World';
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NestJS:使用 JWT 将验证选项添加到 AuthGuard 的相关文章

随机推荐

  • R 控制台是我的母语,如何将 R 设置为英语?

    我在 Windows 7 上使用 R 显然 R 不知何故发现了我说英语以外的语言的证据 并且顽固地坚持在控制台中以我自己的语言提供输出 由于多种原因 这是不可取的 我希望 R 是英语 什么有效 我能够使用LANGUAGE en作为 R 控制
  • 重命名带有“完整工作表”图表的工作表会导致电子表格重新加载

    Google 表格允许将图表移动到自己的表格中 不过 谷歌脚本似乎无法重命名这些工作表 而不会使电子表格崩溃并强制其重新加载 要明白我的意思 请尝试以下操作 1 创建新的电子表格并在其中放入一些数据 2 使用数据创建任何类型的图表 3 编辑
  • AF网络3问题

    In AFNetworking3 表示我使用的 SSL 证书无效验证证书链 false 但现在看来该字段已被删除 我无法向我的服务器发出请求 这是请求类 import UIKit import AFNetworking class Clie
  • Android OpenGL ES 支持无处不在?

    我需要了解如果我选择在 OpenGL 而不是 android graphics 中的 android 原生 2D 图形 API 进行绘图 我会损失多少潜在安装量 android 文档似乎暗示 OpenGL ES API 基本上在所有手机上都
  • 如何从字符串调用并执行运算符?

    例如 var s 3 3 s replace d g function all n1 operator n2 r new Number n1 new Number n2 return r 注意 不使用eval 变量运算符可以吗 https
  • 如何通过其偏移量访问私有数据私有成员?

    我正在尝试按偏移量访问和修改类的私有数据成员 AFAIK 首先是计算偏移量 然后通过偏移量访问成员 这是我的代码 class Test public int a int b private int c Test test cout lt l
  • 如何在 Azure Functions 3.x PowerShell 7 中调用 Azure PowerShell 模块命令?

    我需要运行 Azure PowerShell 模块命令 https learn microsoft com en us powershell azure install az ps view azps 5 2 0 https learn m
  • Python groupby 无法按预期工作[重复]

    这个问题在这里已经有答案了 我正在尝试读取一个 Excel 电子表格 其中包含以下格式的一些列 column1 column1 AccountName column1 SomeOtherFeature column2 blabla colu
  • Active Adblock Plus 在 Chrome JS 控制台中显示奇怪的错误

    我使用 Chrome 浏览的每个页面都会在控制台中显示此错误 扩展 uncaught exception handler 8 事件处理程序中出现错误 未知 SyntaxError 无法在 CSSStyleSheet 上执行 insertRu
  • 当函数定义为无参数时,为什么我可以调用带参数的函数?

    再会 我偶然发现了一些我在 JavaScript 领域从未见过的东西 但我想对于更了解该语言的人来说这是很容易解释的 下面我有以下函数 代码取自书籍 JavaScript Ninja 的秘密 function log try console
  • 查找数组中的重叠数据

    我们正在编写一个 C 应用程序 它将有助于删除不必要的数据重复器 只有在以下情况下才可以移除中继器 all它接收到的数据被其他中继器接收 我们第一步需要做的事情解释如下 例如 我有 int 数组的集合 A 1 2 3 4 5 b 2 4 6
  • 有没有免费的在线 Maven 存储库?

    有没有免费的在线私人maven2或maven3存储库 这样该团队就可以从各个区域访问存储库 如果您使用 github 则可以使用私有 github 项目作为您的 Maven 存储库 这里有关于如何将 Maven 工件发布到 github 的
  • 在 Windows 上安装 RMagick

    我对此进行了研究 并且在我的一台计算机上花了几个小时 大约三周前 我在我的台式计算机上安装了 RMagick 它相当复杂 我不记得我采取的具体步骤 我真的很沮丧 我已将 ImageMagick 安装到我的计算机上的目录 C ImageMag
  • 在屏幕外绘制 uiview

    我想创建一个 UIView 它在调用 ViewDidLoad 时位于屏幕外 但一旦调用某个函数 我就会将其动画显示到屏幕上 用于对 UIView 进行动画处理的代码很好 但我似乎无法从屏幕外绘制 UIView 我已将故事板中的 UIView
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • 具有列顺序的响应式多列列表

    我正在尝试创建一个有序的多列列表 但正在努力解决 CSS 网格布局规则 期望的结果应该是响应式的 在小屏幕上有 2 个网格列 在较大的屏幕上最多有 4 个网格列 同时保持列顺序 而不是像这样排序 1 2 3 4 5 6 7 8 9 10 1
  • 活动片段已清除索引:-1 是什么意思以及如何修复它?

    我有一个带有自定义滑动菜单的活动 用于类似选项卡的界面 由于某种原因 我的一个 且只有一个 片段出现此错误 我似乎找不到它在做什么 这是堆栈跟踪 E FragmentManager 13024 Failure saving state ac
  • 如何修改 Elasticsearch 文档的 _source 字段

    问题 有没有办法从文档的 source 中清除 html html 的剥离可以是周期性的 触发的 或者理想情况下是在索引时即时进行的 我将数据输入到elasticsearch中 并针对分析器进行索引 该分析器在索引之前剥离不需要的htmls
  • 如何将 FAB 转换为弹出菜单?

    根据材料设计指南 https material google com components buttons floating action button html buttons floating action button transit
  • NestJS:使用 JWT 将验证选项添加到 AuthGuard

    我正在尝试利用AuthGuard装饰器和护照 JWT 策略 遵循文档 https docs nestjs com techniques authentication 文档中的所有内容都运行良好 但我现在想保护 JWT 中包含的范围的路由 这