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

受Auth0保护的API测试JWT验证失败及Jest异常问题求解

问题1:mock-jwks生成的token无法通过fastify-auth0-verify验证

根因

fastify-auth0-verify默认校验JWT头的typ字段,而mock-jwks生成token时默认不会携带该字段。

修复方法

调用jwks.token时传入第二个header覆盖参数,手动添加typ: JWT:

const getToken = jwks => {
  const token = jwks.token({
    iss: `https://${process.env.AUTH0_DOMAIN}/`,
    sub: 'testprovider|12345678',
    aud: [
      `${process.env.AUTH0_AUDIENCE}`,
      `https://${process.env.AUTH0_DOMAIN}/userinfo`
    ],
    iat: 1635891021,
    exp: 1635977421,
    azp: 'AndI...3oF',
    scope: 'openid profile email'
  }, { typ: 'JWT' }); // 新增header覆盖配置
  return token;
};

问题2:Jest测试完成后无法正常退出

根因

mock-jwks.start()会启动本地HTTP服务,你当前调用的jwks.stop()是异步方法,没有等待执行完成就结束了测试生命周期,导致服务残留、端口未释放。

修复方法

修改停止服务的逻辑为异步等待,同时关闭fastify实例避免残留连接:

const stopAuthServer = async jwks => {
  await jwks.stop(); // 等待服务关闭完成
};

afterEach(async () => {
  await stopAuthServer(jwks);
  await server.close(); // 关闭fastify实例
});

问题3:nock拦截JWKS请求不生效

根因

你同时混用了mock-jwks的本地服务模式和nock,且没有把fastify-auth0-verify的JWKS请求地址指向mock服务,导致请求直接发往真实Auth0域名,没有命中拦截规则。

可选优化方案:改用无本地服务的mock模式

完全去掉mock-jwks的服务启动/停止逻辑,直接用mock-jwks生成密钥对,配合nock拦截返回公钥,不会启动额外服务,稳定性更高:

const createJWKSMock = require('mock-jwks').default;
const nock = require('nock');

describe('/promoter/event/:id', () => {
  let server, token, jwks;
  const auth0Domain = process.env.AUTH0_DOMAIN;

  beforeEach(async () => {
    jest.clearAllMocks();
    nock.cleanAll();

    // 初始化jwks实例,不需要启动本地服务
    jwks = createJWKSMock(`https://${auth0Domain}`);

    // 生成符合要求的token
    token = jwks.token({
      iss: `https://${auth0Domain}/`,
      sub: 'testprovider|12345678',
      aud: [
        `${process.env.AUTH0_AUDIENCE}`,
        `https://${auth0Domain}/userinfo`
      ],
      iat: 1635891021,
      exp: 1635977421,
      azp: 'AndI...3oF',
      scope: 'openid profile email'
    }, { typ: 'JWT' });

    // nock拦截Auth0 JWKS请求,返回mock公钥
    nock(`https://${auth0Domain}`)
      .get('/.well-known/jwks.json')
      .reply(200, jwks.getJWKS());

    server = require('../../../');
    await server.ready();
  });

  afterEach(async () => {
    await server.close();
    nock.cleanAll();
  });

  // 测试用例保持不变
  it('GET for a non-exising event returns 404', async () => {
    // 原有逻辑不变
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:24:07