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;
关键错误总结
- 认证中间件不应新建Express实例,且必须使用
res.locals存储请求级用户数据; - 路由配置错误导致认证中间件未作用到帖子路由接口,这是
res.locals.user为undefined的核心原因; - 帖子路由无需重复查询数据库,直接使用
res.locals中的用户数据即可。
内容的提问来源于stack exchange,提问作者YO B
相关产品推荐
相关产品推荐

