使用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);
关键说明
- Promise包装:通过Promise把Passport的回调式逻辑转为异步等待,确保tRPC中间件能等到认证完成再继续。
- 正确处理认证结果:不仅要判断
err,还要检查user是否存在——有些场景下err为null但用户未通过认证,这时候也要抛出未授权错误。 - 上下文传递:把认证后的
user挂载到tRPC的ctx上,后续的procedure可以直接通过ctx.user获取用户信息。 - 区分两个next:这里tRPC中间件的
next()是tRPC自身的流程函数,和Passport回调里的Expressnext完全无关,不要混用。
内容的提问来源于stack exchange,提问作者mickyngub
相关产品推荐
相关产品推荐

