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

Node.js Express子路由用中间件报错:Route.post()获undefined回调

问题解决:Express路由中间件导入报错"Route.post() requires a callback function but got a [object Undefined]"

问题场景

为避免server.js主文件臃肿,拆分出包含登录、注册、邮箱验证、密码重置的auth子路由。同时编写了checkAuthenticated(验证已登录)和checkNotAuthenticated(验证未登录)两个中间件,由于不同接口需要不同身份校验逻辑,无法通过app.use()全局挂载。但在auth路由文件中导入这两个中间件并为login接口添加checkNotAuthenticated时,出现报错:Error: Route.post() requires a callback function but got a [object Undefined],移除该中间件后则正常运行。

错误原因

你在server.js中定义的checkAuthenticated、checkNotAuthenticated是普通函数,未通过module.exports导出;同时server.js先引入了authRoute,此时中间件函数还未定义,导致auth路由文件中require('../server')无法获取到这两个函数,最终checkNotAuthenticated为undefined,触发路由回调必须是函数的错误。

解决方法

最合理的方案是将身份校验相关中间件单独抽离为独立文件,既解决导出问题,也让代码结构更清晰:

步骤1:新建中间件文件

创建middleware/auth.js,把所有校验相关函数移到这里并导出:

async function checkJWT(token) {
  try {
    // 原有的JWT校验逻辑
    return user;
  } catch (err) {
    console.log(err);
    return 500;
  }
}

async function checkAuthenticated(req, res, next) {
  const auth = await checkJWT(req.cookies.token);

  if (auth === 500) return res.status(500).send();
  if (!auth) return res.status(401).send();

  req.user = auth;
  return next();
}

async function checkNotAuthenticated(req, res, next) {
  const auth = await checkJWT(req.cookies.token);

  if (auth === 500) return res.status(500).send();
  if (auth) return res.status(401).send();

  return next();
}

module.exports = {
  checkAuthenticated,
  checkNotAuthenticated,
  checkJWT
};

步骤2:修改server.js导入路径

从新的中间件文件导入需要的函数:

const userRoute = require("./routes/user");
const authRoute = require("./routes/auth");
const { checkAuthenticated } = require("./middleware/auth");

const app = express();

(async () => await connection())();

app.use("/auth", authRoute);

app.use("/user", checkAuthenticated, userRoute);

app.listen(3001, () => {
  console.log("backend running on Port: 3001");
});

步骤3:修改auth路由文件导入路径

同样从中间件文件导入checkNotAuthenticated:

const express = require("express");
const { checkNotAuthenticated } = require("../middleware/auth");

const router = express.Router();

router.post("/login", checkNotAuthenticated, async (req, res) => {
  // 原有的登录逻辑
  return res.status(401).send();
});

module.exports = router;

额外说明

这种模块化拆分方式不仅解决了当前导出问题,还避免了潜在的循环依赖风险,同时让代码职责更清晰,后续维护和扩展也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:20:31