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

MERN栈部署至Render/Vercel后req.session缺失用户数据(Cookie存在但无userId)的问题求助

MERN栈部署至Render/Vercel后req.session缺失用户数据(Cookie存在但无userId)的问题求助

我正在部署本地开发好的MERN栈网站,本地调试时所有功能都正常,但把后端部署到Render、前端部署到Vercel后,遇到了会话数据丢失的问题:登录接口返回成功,MongoDB的sessions集合里也能看到存储的userId,但后续接口请求中,req.session里只有cookie相关信息,完全找不到userId字段。本地运行时req.session里既有cookie也有userId,一切正常。

下面是我的核心代码和具体情况,求各位帮忙排查一下问题!


后端核心配置(app.ts)

const app = express()
app.set("trust proxy", 1)
app.use(cors({ 
  origin: ["https://frontend.vercel.app", "http://localhost:3000"], 
  credentials: true 
}))
app.use(morgan("dev"))
app.use(express.json())

export const Session = session({ 
  secret: env.SESSION_SECRET,
  resave: false, 
  saveUninitialized: false, 
  cookie: { 
    maxAge: 720 * 60 * 60 * 1000, 
    httpOnly: true, 
    secure: env.EGE === "production", 
    sameSite: env.EGE === "production" ? "none" : "lax" 
  }, 
  rolling: true, 
  store: MongoStore.create({ mongoUrl: env.MONGO_CONNECTION_STRING }), 
})
app.use(Session)

后端登录接口代码

export const login: RequestHandler<unknown, unknown, loginBody, unknown> = async(req, res, next) => { 
  const username = req.body.username 
  const password = req.body.password 

  try { 
    if(!username || !password){ 
      throw createHttpError(400, "missing parameters") 
    } 

    const user = await UserModel.findOne({username: username}).select("password").exec() 
    if(!user){ 
      throw createHttpError(400, "invalid credentials") 
    } 

    const passwordMatch = await bcrypt.compare(password, user.password) 
    if(!passwordMatch){ 
      throw createHttpError(400, "invalid credentials") 
    } 

    req.session.userId = user._id 
    req.session.save(err => { 
      if (err) return next(err); 
      res.status(200).json(user); 
    }) 
  } catch (error) { 
    next(error) 
  } 
}

前端登录请求代码

async function fetchData(input: RequestInfo, init?: RequestInit) { 
  const response = await fetch(input, init) 
  if(response.ok){ 
    return response 
  } else{ 
    try { 
      const errorBody = await response.json() 
      const errorMessage = errorBody.error 
      throw new Error(errorMessage) 
    } catch (error) { 
      throw new Error("failed to parse error") 
    } 
  } 
} 

export async function login(credentials: LoginCredentials): Promise<User> { 
  const response = await fetchData(`${process.env.REACT_APP_BACKEND_URL}/api/users/login`,{ 
    method: "POST", 
    headers: { "Content-Type": "application/json" }, 
    credentials: "include", 
    body: JSON.stringify(credentials) 
  }) 
  return response.json() 
}

具体现象对比

本地环境

  • 登录后,req.session.userId被正确设置,打印req.session能看到userId字段
  • MongoDB的sessions集合中,对应的会话文档包含userId数据

生产环境(Render+Vercel)

  • 登录接口返回200成功,MongoDB的sessions集合中能看到包含userId的会话文档
  • 后续接口请求时,打印req.session只能看到cookie相关的键值对,完全没有userId
  • 已经尝试调整CORS的origin、credentials配置,也检查了Render的代理信任设置(已经加了app.set("trust proxy", 1)),但都没解决问题

我现在实在摸不着头脑,有没有大佬遇到过类似的问题?求指点!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:48:05