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

使用express-jwt时遇TypeError: jwt is not a function错误求助

解决express-jwt报错:TypeError: jwt is not a function

问题描述

使用express-jwt做身份验证时触发如下错误:

required: jwt({
^
TypeError: jwt is not a function
at file:///C:/Users/atala/Desktop/atalayapp-main/backend/middleware/auth/auth.js:12:15
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:61:12)

我的auth.js代码:

import jwt from "express-jwt";
const getTokenFromHeaders = (req) => {
    const { headers: { authorization } } = req

    if (authorization && authorization.spilt(' ')[0] === 'Token') {
        return authorization.split(' ')[1]
    }
    return null
}

const auth = {
    required: jwt({
        secret: " /\-l/\Y",
        userProperty: 'payload',
        getToken: getTokenFromHeaders
    }),
    optional: jwt({
        secret: "/\-l/\Y",
        userProperty: 'payload',
        getToken: getTokenFromHeaders,
        credentialsRequired: false,
    })
}

export default auth

路由使用代码:

router.post("/login", auth.optinal, (req, res, next) => {
    const { body: { user } } = req

    if (!user.email && !user.password) {
        return res.status(402).json({
            errors: "Eposta veya şifre yanlış ! ",
        });

        return passport.authenticate('local', { session: false }, (err, passportUser, info) => {
            if (err) {
                return next(err)
            }
            if (passportUser) {
                const user = passportUser
                user.token = passportUser.genareteJWT();
                return res.json({ user: user.toAuthJSON() })
            }
            return res.status(400).info;

        })(req, res, next)
    }
})

核心原因

express-jwt从v4版本起导出方式变更:不再默认导出jwt函数,而是通过**命名导出expressjwt**提供核心功能;同时新版本要求必须指定签名算法(如HS256)。

解决方案

1. 修正auth.js的导入与配置

替换导入方式并补充算法配置,同时修复拼写错误:

import { expressjwt } from "express-jwt";

const getTokenFromHeaders = (req) => {
    const { headers: { authorization } } = req

    // 修复拼写错误:spilt → split
    if (authorization && authorization.split(' ')[0] === 'Token') {
        return authorization.split(' ')[1]
    }
    return null
}

const auth = {
    required: expressjwt({
        secret: " /\-l/\Y",
        algorithms: ["HS256"], // 新版本必须指定签名算法
        userProperty: 'payload',
        getToken: getTokenFromHeaders
    }),
    optional: expressjwt({
        secret: "/\-l/\Y",
        algorithms: ["HS256"],
        userProperty: 'payload',
        getToken: getTokenFromHeaders,
        credentialsRequired: false,
    })
}

export default auth

2. 修复路由代码中的错误

修正拼写错误与逻辑问题:

router.post("/login", auth.optional, (req, res, next) => {
    const { body: { user } } = req

    // 逻辑修正:邮箱或密码为空都应该报错,用||而非&&
    if (!user.email || !user.password) {
        return res.status(402).json({
            errors: "Eposta veya şifre yanlış ! ",
        });
    }

    // 原代码中if语句内的return会阻断后续代码执行,将authenticate移到外部
    return passport.authenticate('local', { session: false }, (err, passportUser, info) => {
        if (err) {
            return next(err)
        }
        if (passportUser) {
            const user = passportUser
            // 修复拼写错误:genareteJWT → generateJWT
            user.token = passportUser.generateJWT();
            return res.json({ user: user.toAuthJSON() })
        }
        // 修复错误:.info不是响应方法,改为返回info对象
        return res.status(400).json(info);

    })(req, res, next)
})

额外提醒

  • 密钥(secret)建议存放在环境变量中,避免硬编码泄露风险;
  • 若仍使用express-jwt v3及以下版本,可继续默认导入,但建议升级到新版本获取安全更新。

内容的提问来源于stack exchange,提问作者Atalay Özyıldırım

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:21:35