在 Express、Redis 和 Next.js 的跨源响应中未发送会话 cookie 的问题

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

我正在开发一个具有 Express.js 后端和 Next.js 前端的应用程序。我的后端使用

Redis
connect-redis
包进行会话管理,我的服务器部署在带有
Heroku-Data for Redis
插件的 Heroku 上。 我遇到一个问题,尽管配置了 CORS 标头以接受凭据,但会话 cookie 并未在跨源上下文中从服务器发送到前端。 以下是我的服务器端 (Express.js) 配置的摘录:

// app.js

...

// initialize Redis
async function initializeRedis() {
  
  const redisClient = redis.createClient({
    url: process.env.REDIS_TLS_URL, // url provided by Heroku-Data for Redis
    socket: {
      tls: true,
      rejectUnauthorized: false,
    },
  });

  redisClient.on("error", function (error) {
    console.error("Erreur de Redis :", error);
  });

  await redisClient.connect().catch(console.error);

  return redisClient;
}

// start app
async function startApp() {

  /* Redis
  -------------------------------------------------- */

  const redisClient = await initializeRedis();

  const redisStore = new RedisStore({ client: redisClient });

  /* Express Session
-------------------------------------------------- */

  const sessionConfig = {
    store: redisStore, 
    secret: process.env.EXPRESS_SESSION_SECRET_KEY,
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 600000, // 10 minutes
      secure: process.env.NODE_ENV === "production",
      httpOnly: true,
      sameSite: process.env.NODE_ENV === "production" ? "None" : "Strict",
    },
  };

  /* CORS
-------------------------------------------------- */

  const cors = require("cors");

  const corsOptions = {
    origin: "https://www.my-site.app", 
    methods: ["GET", "POST"], 
    allowedHeaders: ["Content-Type", "Authorization"], 
    credentials: true,
  };

...
}

这是我在客户端(Next.js)发出请求的方式:

// this request creates the session in the backend, storing the order id in the session cookie
const response = await fetch(
  `${process.env.NEXT_PUBLIC_SERVER_ENDPOINT}/validate-order`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(order),
    credentials: "include",
  }
);
// this request is supposed to receive the cookie from the session
 try {
      const response = await fetch(
        `${process.env.NEXT_PUBLIC_SERVER_ENDPOINT}/get-order-id`,
        {
          method: "GET",
          credentials: "include",
        }
      );

向我的 API 发出请求时,客户端不会收到会话 cookie(我的前端通过 https 部署到 Vercel)。响应标头中没有 cookie。我已经检查过,并且确信该问题与 CORS 配置无关,因为适当的标头似乎已就位,并且确实允许跨源请求。

有人遇到过这个问题或者知道可能出了什么问题吗?我可能缺少 Heroku 或 Redis 配置的某些特定内容吗?

预先感谢您的帮助。

我尝试过的:

  • 当我查看 Redis 数据库时,我可以看到密钥已正确创建并且不为空:

    sess:e22dFw38IpASoyv3Hk-xxx

  • 我注意到我可以通过 Express-Session cookie 的此配置正确接收 cookie :

secure : false,
sameSite : « Strict »

但仅当请求来自 http://localhost:3000 并且服务器在本地运行时。当服务器使用此配置在 Heroku 上运行时,我没有收到 cookie。

  • 我将

    maxAge
    cookie 参数更新为 2 小时,以确保问题与时区无关

  • 将我的服务器部署在自定义域上,并启用 Heroku SSL,如此线程中所述。前端仍然没有 cookie。

  • domain
    参数添加到
    app.js
    中的 cookie 配置中,如此处所述:

  const sessionConfig = {
    ...
    cookie: {
      ...
      domain: ".my-site.app", // do this only if your server and your front-end share the same domain, with your server on a subdomain like api.my-site.app
    },
  };
express heroku next.js redis session-cookies
1个回答
0
投票

通过将

app.set("trust proxy", 1);
添加到服务器(如此处所述)来解决问题。

像 Heroku 这样的云服务经常使用反向代理,因此这一行告诉 Express 初始请求是通过 https 发出的,即使它是在代理之后通过 http 传输的。

© www.soinside.com 2019 - 2024. All rights reserved.