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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:25:19