You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS的node-oidc-provider中为JWT访问令牌添加自定义属性?

在NestJS+node-oidc-provider中为JWT访问令牌添加自定义roles属性

要给JWT访问令牌添加roles属性,你可以通过node-oidc-provider的两种配置方式实现,以下是具体方案:

方案一:全局配置extraTokenClaims

在node-oidc-provider的初始化配置中添加extraTokenClaims函数,该函数可获取上下文、用户、客户端等信息,返回需要注入的自定义声明:

const oidc = new Provider('http://localhost:3000', {
  // 其他基础配置...
  extraTokenClaims: async (ctx, token, client, user) => {
    // 从用户对象中获取角色,需确保user已包含roles字段(可在认证阶段从数据库查询注入)
    const userRoles = user?.roles || [];
    return {
      roles: userRoles
    };
  },
  // 你的resourceIndicators原有配置
  resourceIndicators: {
    defaultResource(ctx) {
      return ctx.origin;
    },
    getResourceServerInfo(ctx, resourceIndicator, client) {
      return {
        scope: client.scope as string,
        audience: 'account',
        accessTokenFormat: 'jwt',
      };
    },
    useGrantedResource(ctx, model) {
      return true;
    },
  },
});

方案二:针对资源配置额外声明

如果需要根据不同资源返回不同角色,可在getResourceServerInfo中添加extra字段,该字段会被合并到JWT令牌:

resourceIndicators: {
  defaultResource(ctx) {
    return ctx.origin;
  },
  async getResourceServerInfo(ctx, resourceIndicator, client) {
    // 从上下文获取当前用户,需确保认证阶段已将用户信息注入ctx.state.user
    const currentUser = ctx.state.user;
    const userRoles = currentUser?.roles || [];
    
    return {
      scope: client.scope as string,
      audience: 'account',
      accessTokenFormat: 'jwt',
      extra: {
        roles: userRoles
      }
    };
  },
  useGrantedResource(ctx, model) {
    return true;
  },
},

后续守卫校验示例

生成的JWT会包含roles字段,你可以在NestJS守卫中解析令牌并校验角色:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const authHeader = request.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return false;
    }
    const token = authHeader.split(' ')[1];
    const decoded = this.jwtService.verify(token);
    
    // 校验是否包含目标角色,示例为校验admin角色
    return decoded.roles?.includes('admin');
  }
}

内容的提问来源于stack exchange,提问作者ziad696

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:57:50