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

使用Passport.js时如何调用tRPC中间件的next()函数?

解决Passport.js结合tRPC中间件JWT认证的回调next()无效问题

你遇到的错误是因为tRPC中间件依赖Promise异步处理,而你直接混用了Express风格的Passport回调逻辑,两者的next函数上下文不匹配,导致tRPC无法正确捕获中间件的执行结果。

问题根源

  • Passport的passport.authenticate是Express风格的中间件,它的回调参数里的next是Express的中间件流转函数,不是tRPC中间件的next。
  • tRPC中间件要求必须返回一个Promise或者调用tRPC的next()后的结果,你当前的写法里,Passport回调里的return next()并没有被tRPC的中间件函数正确接收,导致tRPC认为中间件没有返回结果。

修正方案

把Passport的认证逻辑包装成Promise,让tRPC可以等待认证完成后再执行自身的next():

const t = initTRPC.create();
const { TRPCError } = require('@trpc/server');

const jwtMiddleware = t.middleware(async ({ ctx, next }) => {
  // 将Passport认证转为Promise异步处理
  await new Promise((resolve, reject) => {
    passport.authenticate('jwt', { session: false }, (err, user) => {
      // 处理错误或未找到用户的情况
      if (err || !user) {
        reject(new TRPCError({ code: 'UNAUTHORIZED' }));
        return;
      }
      // 可选:将认证后的用户挂载到ctx,供后续procedure使用
      ctx.user = user;
      resolve();
    })(ctx.req, ctx.res);
  });

  // 认证通过后,执行tRPC的next继续流转
  return next();
});

const authedProcedure = t.procedure.use(jwtMiddleware);

关键说明

  1. Promise包装:通过Promise把Passport的回调式逻辑转为异步等待,确保tRPC中间件能等到认证完成再继续。
  2. 正确处理认证结果:不仅要判断err,还要检查user是否存在——有些场景下err为null但用户未通过认证,这时候也要抛出未授权错误。
  3. 上下文传递:把认证后的user挂载到tRPC的ctx上,后续的procedure可以直接通过ctx.user获取用户信息。
  4. 区分两个next:这里tRPC中间件的next()是tRPC自身的流程函数,和Passport回调里的Express next完全无关,不要混用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:55:20