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

如何获取当前登录用户并追加至JSON文件?解决req.user未定义问题

解决Express中req.user未定义的问题

首先,你碰到的Cannot read property 'user' of undefined错误,核心原因是请求对象req里没有被正确注入登录用户的信息——简单说就是负责身份验证的中间件没正常工作,导致req压根没有user这个属性。下面一步步帮你排查和解决:

一、先确认你有没有配置身份验证中间件

req.user几乎都是由身份验证中间件(比如Passport.js、express-session配合自定义验证,或者JWT中间件)添加到请求对象里的。如果没配置这类中间件,req自然不会有user属性。

给你列几个常见场景的解决方案:

1. 如果你用的是Passport.js

这是Express生态里最常用的身份验证工具,得先把基础配置做对:

const express = require("express");
const session = require("express-session");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;

const app = express();

// 先配置会话中间件——这是Passport存储用户信息的基础
app.use(session({
  secret: "your-own-secret-key", // 换成你自己的密钥,别用示例里的
  resave: false,
  saveUninitialized: false
}));

// 初始化Passport并启用会话支持
app.use(passport.initialize());
app.use(passport.session());

// 配置序列化/反序列化——把用户对象存进会话、从会话取出来
passport.serializeUser((user, done) => {
  done(null, user.id); // 一般存用户ID就行,不用存整个对象
});

passport.deserializeUser((id, done) => {
  // 这里写你从数据库/用户存储里根据ID拿用户的逻辑
  User.findById(id, (err, user) => {
    done(err, user);
  });
});

// 配置本地登录策略(如果用用户名密码登录)
passport.use(new LocalStrategy(
  (username, password, done) => {
    // 这里写你的用户校验逻辑:查用户、验密码
    User.findOne({ username: username }, (err, user) => {
      if (err) return done(err);
      if (!user) return done(null, false, { message: "用户名不存在" });
      if (!user.checkPassword(password)) return done(null, false, { message: "密码错啦" });
      return done(null, user);
    });
  }
));

然后,在需要用req.user的路由上,要么用passport.authenticate()中间件,要么用自定义的验证中间件保护:

// 登录接口
app.post("/login", passport.authenticate("local"), (req, res) => {
  // 登录成功后,req.user就已经被设置好了
  res.redirect("/dashboard");
});

// 需要登录才能访问的路由,用自定义中间件保护
app.get("/dashboard", ensureAuthenticated, (req, res) => {
  // 这里可以放心用req.user了
  console.log(req.user);
  res.send(`欢迎回来,${req.user.username}`);
});

// 自定义的登录校验中间件
function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect("/login");
}

2. 如果你用的是JWT(无会话验证)

这种方式不需要会话,靠请求头里的Token来验证,得自己写中间件解析Token并注入用户信息:

const jwt = require("jsonwebtoken");

// 自定义JWT验证中间件
function authenticateToken(req, res, next) {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1]; // Token格式是Bearer <token>

  if (!token) {
    return res.sendStatus(401); // 没Token直接返回未授权
  }

  jwt.verify(token, "your-jwt-secret", (err, user) => {
    if (err) return res.sendStatus(403); // Token无效返回禁止访问
    req.user = user; // 把解析后的用户信息挂载到req.user
    next();
  });
}

// 在需要验证的接口上用这个中间件
app.post("/append-user", authenticateToken, (req, res) => {
  // 这里就能正常用req.user了
  console.log(req.user);
  // 接下来写追加到JSON文件的逻辑
  const userInfo = req.user;
  fs.readFile("./target-file.json", "utf8", (err, data) => {
    if (err) {
      console.error(err);
      return res.status(500).send("读取文件失败");
    }
    let jsonContent = JSON.parse(data);
    jsonContent.loggedUsers.push(userInfo); // 假设你的JSON里有loggedUsers数组
    fs.writeFile("./target-file.json", JSON.stringify(jsonContent, null, 2), (err) => {
      if (err) {
        console.error(err);
        return res.status(500).send("写入文件失败");
      }
      res.send("用户信息已成功追加");
    });
  });
});

二、检查路由的中间件顺序和参数

有时候不是中间件没配置,是顺序错了或者路由函数写法不对:

  • 身份验证中间件必须放在需要用req.user的路由前面,不然路由执行时还没注入用户信息;
  • 确保你的路由函数是(req, res, next) => {}的形式,req是第一个参数,别写漏了。

三、调试小技巧

要是还是搞不清问题出在哪,可以在路由里先打印req看看:

app.get("/debug-user", (req, res) => {
  console.log(req); // 打印整个req对象,看看有没有user属性
  if (req.isAuthenticated) {
    console.log(req.isAuthenticated()); // 用Passport的话,这个方法能判断用户是否登录
  }
  res.send("调试信息已经打印到控制台啦");
});

按照上面的步骤排查,应该就能解决req.user未定义的问题,之后你就能顺利把当前登录用户的信息追加到JSON文件里啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:54:45