TypeScript Node.js JWT认证中间件类型错误排查求助
解决Node.js JWT认证中间件的TypeScript类型错误
问题梳理
开发基于Express的JWT登录认证中间件时遇到三个TypeScript类型错误:
- 错误1:
Property 'client' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' - 错误2:Prisma查询参数类型不匹配
- 错误3:路由使用中间件时参数类型不兼容,提示
Property 'client' is missing in type 'Request...' but required in type 'GetClientAuthInfoRequest'
分步解决方案
1. 全局扩展Express Request类型
自定义单独接口会导致路由中类型不兼容,正确做法是全局扩展Express的Request类型:
在项目根目录创建types/express/index.d.ts文件(无则新建),写入以下内容:
import { Client } from '../path-to-your-client-type'; // 替换为你的Client类型实际路径 declare global { namespace Express { interface Request { client?: Client | null; } } }
确保tsconfig.json包含该类型文件路径:
{ "compilerOptions": { "typeRoots": ["./node_modules/@types", "./types"] } }
2. 修复Prisma查询参数错误
原代码中prisma.client.findUnique({ decoded.id })参数格式错误,findUnique需接收where对象:
// 原错误代码 req.client = await prisma.client.findUnique({ decoded.id }); // 修复后 const decoded = jwt.verify(token, "sgjlskdfghajhdfghsd") as JwtPayload; req.client = await prisma.client.findUnique({ where: { id: decoded.id } // 符合Prisma要求的参数格式 });
同时给jwt.verify添加类型断言,让TypeScript识别解码后的payload类型。
3. 修正中间件的类型与逻辑
- 直接使用扩展后的
Request类型作为参数 - 处理token不存在、验证失败、用户未找到等异常场景
- 确保中间件遵循Express请求处理器格式,调用
next()传递请求
修正后的Auth类代码:
import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; import prisma from '../path-to-your-prisma-client'; // 替换为你的Prisma客户端路径 interface JwtPayload { id: string; } export class Auth { async isAuthenticatedClient(req: Request, res: Response, next: NextFunction) { const { token } = req.cookies; if (!token) { return res.status(401).send({ message: "Faça login para acessar esse conteúdo" }); } try { const decoded = jwt.verify(token, "sgjlskdfghajhdfghsd") as JwtPayload; const client = await prisma.client.findUnique({ where: { id: decoded.id } }); if (!client) { return res.status(401).send({ message: "Usuário não encontrado" }); } req.client = client; next(); // 传递请求到下一个中间件/控制器 } catch (error) { return res.status(401).send({ message: "Token inválido" }); } } }
4. 路由中的正确使用
现在可直接在路由中使用中间件,无类型冲突:
router.route('/teste').get(authMiddleware.isAuthenticatedClient, authController.teste);
注意:中间件顺序要正确,先执行认证中间件,再执行业务控制器。
关键说明
- 全局扩展Express类型是解决
req.client类型错误的核心,避免自定义接口导致的类型不兼容 - Prisma的
findUnique必须严格按照{ where: { 字段: 值 } }格式传参 - 中间件必须处理异常场景并调用
next(),否则请求会挂起
内容的提问来源于stack exchange,提问作者Pedro Souza
相关产品推荐
相关产品推荐

