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

Express如何将用户会话存入request对象及req.user的来源解析

req.user._id的来源

你学习的这个MERN项目采用JWT(JSON Web Token)身份验证方案,没有使用服务端会话存储机制,因此不需要安装express-session、cookie-session这类依赖,req.user是由自定义的身份校验中间件挂载到请求对象上的:

  1. 用户登录时,后端校验账号密码无误后,会生成携带用户ID信息的JWT返回给前端
  2. 前端后续发起需要登录权限的请求(比如下单接口)时,会把JWT放到Authorization请求头中,格式为Bearer <token值>
  3. 请求到达下单接口前,会先经过全局/路由绑定的身份校验中间件,中间件会取出请求头的JWT做有效性校验,校验通过后会根据JWT内的用户ID查询对应用户信息,挂载到req.user属性上,再放行到后续的接口逻辑
  4. 因此你在addOrderItems接口中可以直接读取req.user._id获取当前登录用户的ID

对应身份校验中间件的示例代码如下:

const jwt = require('jsonwebtoken')
const User = require('../models/userModel')
const asyncHandler = require('express-async-handler')

// 身份校验中间件
const protect = asyncHandler(async (req, res, next) => {
  let token
  // 读取请求头中的JWT
  if (req.headers.authorization?.startsWith('Bearer')) {
    try {
      token = req.headers.authorization.split(' ')[1]
      // 解密JWT,校验有效性
      const decoded = jwt.verify(token, process.env.JWT_SECRET)
      // 查询用户信息,排除密码字段后挂载到req.user
      req.user = await User.findById(decoded.id).select('-password')
      // 放行到下一个中间件/路由处理器
      next()
    } catch (err) {
      res.status(401)
      throw new Error('Token无效,无权访问')
    }
  }
  if (!token) {
    res.status(401)
    throw new Error('未提供Token,无权访问')
  }
})

路由层会把这个中间件绑定到需要登录的接口上,示例如下:

// 只有经过protect中间件校验通过的请求,才能进入addOrderItems逻辑
router.post('/api/orders', protect, addOrderItems)

Express中将用户信息存入request对象的实现方式

核心是通过Express中间件机制实现,中间件可以在请求的生命周期内修改req对象,所有后续执行的中间件、路由处理器都能访问到修改后的内容,常见实现方案分为两种:

  • 会话存储方案:引入express-session等中间件,用户登录校验通过后,将用户信息存入req.session.user,也可以额外加一层中间件把req.session.user赋值到req.user简化调用
  • JWT无状态方案:和上面的项目逻辑一致,自定义JWT校验中间件,校验通过后把用户信息直接挂载到req.user上即可

需要注意中间件的注册/绑定顺序必须早于对应的路由处理器,否则路由执行时还未挂载对应的用户信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:48:05