Express 会话不会跨请求持续存在,并且不会在浏览器中设置 cookie - 在生产中(客户端和服务器托管在单独的 url 上)

问题描述 投票:0回答:0

我正在开发一个电子商务应用程序,在前端使用 React (Vite)、Node、MySQL、Sequelize 和 Express,并带有 Express-Session 和 Sequelize 会话存储。虽然一切都在本地运行,但在生产中,我发现我的 cookie 没有存储在浏览器中,并且当我在托管在单独的 url 上的客户端和服务器之间进行通信时,我的会话不会持续存在。过去一周我一直在尝试一切方法来解决这个问题,但没有成功。我什至不确定此时是否可以修复,但非常感谢任何见解。

我的后端严重依赖快速会话来创建 cookie 并存储用于身份验证的用户 ID,并在我的各种路由上获取登录用户的数据。我的客户端代码独立存在,并通过获取请求与后端通信。在本地,我将所有对 /api 的客户端请求设置为代理到本地运行的 Express 服务器,如我的 vite.config 文件中所示:

export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      "/api": "http://localhost:3000/", // Replace with your backend server URL
      "/shop": "http://localhost:3000/",
    },
  },
});

当我从前端点击 /api/user/login 端点时,我已登录并可以在浏览器中看到一个新的 cookie 设置。我能够通过网络请求刷新和维护我的登录状态。

但是,在生产中我无法再使用代理。我将前端 React 应用程序部署到 netlify,它发出的每个获取请求都会转到 Heroku 上托管的服务器的 url。

fetch("https://gentle-spire-83185-d5ea8d952a7d.herokuapp.com/api/user/login", {
  credentials: "include",
});

我仍然可以登录并看到登录路由 console.logs 带有 cookie 和我的 userId 的 req.session。我还在网络选项卡中看到我的登录请求的响应中确实附加了一个 cookie。但是,我没有在应用程序选项卡中看到任何 cookie 设置,在 Netlify 站点或 Heroku 上的服务器中都没有看到。如果我尝试导航到需要定义 req.session.userId 的不同路径,则会收到未登录错误。同样,当我刷新时,我会返回登录页面,会话中没有保存任何数据。很明显,cookie 没有被设置,我的 userId 也没有在跨网络请求的会话中维护。

Cookie showing in network tab

Console after logging in (shows my userId on session)

但是 netlify 网站或托管后端的 heroku 网站的浏览器中没有显示 cookie:

我的 Express 会话配置:

app.set("trust proxy", 1);

app.use(
  cors({
    origin: "https://main--gorgeous-duckanoo-f2f18a.netlify.app",
    credentials: true,
  })
);

// use the express session middleware providing options
app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    store: new SequelizeStore({
      db: sequelize,
    }),
    cookie: {
      maxAge: 1000 * 60 * 60 * 12,
      sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
      secure: process.env.NODE_ENV === "production",
      path: "/",
      domain: "main--gorgeous-duckanoo-f2f18a.netlify.app",
    },
  })
);

登录途径:

router.post("/login", async (req, res) => {
  // check db for matching username
  const existingUser = await User.findOne({
    where: {
      email: req.body.email,
    },
  });

  if (!existingUser) {
    return res.status(404).send({ error: "incorrect credentials" });
  }

  // compare password using instance method defined on user model
  if (existingUser.checkPassword(req.body.password, existingUser.password)) {
    // set and save logged in user on session object
    req.session.userId = existingUser.id;
    req.session.save(function (err) {
      if (err) return next(err);
    });
    console.log(req.session);
    return res.status(200).send(req.session);
  }
  
  // if wrong password
  return res.status(404).send({ error: "incorrect credentials" });
});

我见过的每一个修复都与更改 cookie 设置有关,但我尝试过但没有成功。我没有收到任何与 cors 或我的服务器相关的错误,只是缺少设置我需要修复的 cookie。

node.js reactjs express session session-cookies
© www.soinside.com 2019 - 2024. All rights reserved.