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

Express项目中res.locals.user获取失败问题求助(附代码)

res.locals返回undefined问题的排查与解决

核心问题

认证中间件中能正常输出用户信息,但在帖子创建接口中res.locals.user始终返回undefined,无法获取当前登录用户。


1. 认证中间件的错误修正

问题点:中间件内新建了独立的Express实例,且错误使用全局应用级的app.locals存储用户信息,而非请求级的res.locals。

修正后的代码:

// middlewares/auth-middleware.js
const jwt = require("jsonwebtoken");
const User = require("../schemas/user");

// 移除多余的Express实例创建
// const express = require("express");
// const app = express();

module.exports = async (req, res, next) => {
  const { Authorization } = req.cookies;
  const [authType, authToken] = (Authorization ?? "").split(" ");

  if (!authToken || authType !== "Bearer") {
    res.status(401).send({
      errorMessage: "(1)请先登录。",
    });
    return;
  }

  try {
    const { userId } = jwt.verify(authToken, "customized-secret-key");
    const user = await User.findById(userId);
    // 将用户信息存入请求级的res.locals,而非全局app.locals
    res.locals.user = user;
    console.log(res.locals.user);
    next();
  } catch (err) {
    console.error(err);
    res.status(401).send({
      errorMessage: "(2)请先登录。",
    });
  }
};

2. 帖子路由的逻辑修正

问题点:未正确从res.locals获取用户,且存在重复查询数据库的冗余逻辑。

修正后的代码:

// routes/post.js
router.post("/", authMiddleware, async (req, res) => {
  // 从res.locals直接获取已验证的用户
  const user = res.locals.user;
  console.log(user);
  
  const { title, content } = req.body;
  console.log(title, content);

  // 无需重复查询数据库,直接判断用户是否存在
  if (user) {
    // 创建帖子时关联用户ID
    await Post.create({ title, content, userId: user._id });
    res.json({ result: "success" });
  } else {
    res.status(401).json({ errorMessage: "请先登录" });
  }
});

3. app.js路由配置的关键错误

问题点:认证中间件仅挂载到/auth路径下,导致/api/posts等接口根本不会经过认证中间件,这是最核心的配置错误。

修正后的代码:

// app.js
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const dotenv = require('dotenv')
const port = process.env.PORT || 5500;
const app = express();
const cookieParser = require("cookie-parser");

dotenv.config();
app.use(express.json())
app.use(cookieParser());
app.use(express.urlencoded({extended:false}))

// 错误:原代码仅让/auth路径经过认证中间件
// app.use("/auth", require("./middlewares/auth-middleware"));
// 方案1:全局挂载认证中间件(所有接口都需认证)
app.use(require("./middlewares/auth-middleware"));

// 方案2:仅给需要认证的路由挂载中间件(更灵活)
// const authMiddleware = require("./middlewares/auth-middleware");
// app.use("/api/posts", authMiddleware, require("./routes/posts"));

// 路由配置
app.use("/api/posts", require("./routes/posts"));
app.use("/api/users", require("./routes/users"));
app.use("/api", require("./routes/comments"));

// MongoDB连接修正:添加箭头函数避免立即执行
mongoose.connect(process.env.MONGO_URL,)
.then(() => console.log("Successfully connected to mongodb"))
.catch((err) => console.log(err))

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

// 导出app而非无用的router
module.exports = app;

关键错误总结

  1. 认证中间件不应新建Express实例,且必须使用res.locals存储请求级用户数据;
  2. 路由配置错误导致认证中间件未作用到帖子路由接口,这是res.locals.user为undefined的核心原因;
  3. 帖子路由无需重复查询数据库,直接使用res.locals中的用户数据即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:53:17