受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
相关产品推荐
相关产品推荐

