Express/Heroku - 在服务器网络应用程序而不是客户端网络应用程序上设置 Cookie

Express/Heroku - Cookie set on server web app instead of client web app

我遇到这种情况,在部署到 Heroku 之后,我的 cookie 没有设置到客户端。当 运行 localhost 时,cookie 会按预期设置并正常工作,但在部署到 Heroku 后,cookie 会设置在后端 Web 应用程序而不是客户端(我希望设置它的位置)。

客户端部署为下面第一个web app,服务端部署为后面,所以它们是分开的

当我在部署(反应)后登录到客户端时,cookie 没有设置在那里,而是设置在后端应用程序上。所以cookie设置成功,但不是我的客户端。

为什么饼干会在这里结束?!我想要客户端上的 cookie

我的 express、cookie-parser、cors 应用程序如下所示:

const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const mongoose = require("mongoose");
var cookieParser = require("cookie-parser");

const app = express();
const PORT = process.env.PORT || 4040;
require("dotenv").config();

//connect to db
mongoose.connect(
  process.env.MONGODB_URI ||
    `mongodb+srv://${process.env.MONGODB_USER}:${process.env.MONGODB_PASSWORD}@shopproject.xaroy.mongodb.net/shopitems?retryWrites=true&w=majority`,
  {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  }
);

mongoose.connection.on("connected", () => {
  console.log("Connected to Mongodb");
});

//middleware

app.set("trust proxy", 1);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

app.use(
  cors({
    origin: ["https://gigvilla.herokuapp.com", "http://gigvilla.com"],
    credentials: true,
    allowedHeaders: [
      "Content-Type",
      "Accept",
      "Origin",
      "X-Requested-With",
      "Authorization",
      "Set-Cookie",
    ],
  })
);

//http req logger
app.use(morgan("tiny"));

app.get("/", (req, res) => {
  res.cookie("trol", "valle").send("hello");
});

//Getting routes to app
const authRoutes = require("./routes/auth");
const shopRoutes = require("./routes/shop");
const storeRoutes = require("./routes/store");
//below test

app.use(authRoutes);
app.use(shopRoutes);
app.use(storeRoutes);
// app.use(storeRoutes);
//test

app.listen(PORT, console.log(`server is running at ${PORT}`));

使用以下代码段发送 cookie

exports.loginUser = async (req, res, next) => {
  //Validate
  const { error } = loginValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  //Check for existing user
  const user = await User.findOne({ email: req.body.email.toLowerCase() });
  if (!user) return res.status(400).send("Email does not exist");

  if (user.authenticated === false) return res.status(400).send("Not verified");

  //Password is correct
  const validPass = await bcrypt.compare(req.body.password, user.password);
  if (!validPass) return res.status(400).send("Invalid password");

  //Create and assign JWT token
  const token = jwt.sign(
    { userId: user._id, userName: user.user },
    process.env.JWT_TOKEN_SECRET
  );
  res
    .status(202)
    .cookie("Authorization", "Bearer " + token, {
      httpOnly: true,
      maxAge: 3600000,
      sameSite: "none",
      secure: true,
    })
    .cookie("just testing", "my name is", {
      httpOnly: false,
      maxAge: 3600000,
      sameSite: "none",
      secure: true,
      path: "/",
    })
    .json({ userName: user.user });
};

有人知道怎么解决吗?在这一点上变得非常绝望..(16 小时..)

Herokuapp.com 包含在 Mozilla 基金会的 Public 后缀列表中,因此它将阻止您在 herokuapp.com 或 *.herokuapp.com 上设置 cookie。您可以查看列表 here.

我建议您将其托管在可以帮助您设置 cookie 的任何其他云提供商上。

此外,您可以查看 heroku dev center 为什么不允许设置 cookie。这可能会帮助您理解问题不在于代码,而在于托管。

如果您曾经 运行 解决过这个问题,这是 Apoorva 在上面提供的帮助以及将您的服务器端添加到客户端域的子域的混合。

当服务器和客户端分别设置为客户端:“customdomain.com”服务器:api.customdomain.com时,cookie 可以设置为: .cookie("Authorization", "Bearer" + token, { httpOnly:是的, 最大年龄:3600000, 域:“gigvilla.com”,

  // below to be added when running on https
  // sameSite: "none",
  // secure: true,
})

“域”部分确保也为客户端设置了 cookie。