无法使用 Netlify 和 Heroku 跨域设置/接收 cookie

2023-11-30

我遇到了无法在浏览器中设置 cookie 的问题,因为客户端托管在 Netlify 上,服务器托管在 Heroku 上。它在本地主机上运行良好,所以看起来它现在与跨域有关。

阅读了多篇关于此的文章后,似乎这可能与 cors 或我如何设置 cookie 有关。

我在某处读到它可能有助于添加secure: true and sameSite: "none"设置cookie时,所以我添加了它们,但没有帮助。我也尝试过添加domain设置时将其写入cookie,但不幸的是它也没有帮助。

我正在使用 Chrome,并已将设置从阻止第三方 cookie 更改为允许所有 cookie,因为我读到这有时可能是一个问题。然而它也没有产生任何新的结果。

我还读到,无论出于何种原因,它可能需要代理,或者可以通过在 Heroku 上托管客户端和服务器来解决这个问题。如果可能的话,我宁愿不做任何这些事情,但欢迎任何想法。

服务器端使用 Heroku 上托管的 Node js (express):

const express = require("express");
const app = express();
require("dotenv").config();
const cors = require("cors");
const mysql = require("mysql");
const jwt = require("jsonwebtoken");
const cookieParser = require("cookie-parser");

// port for heroku if needed
const PORT = 3001;

// app objects instantiated on creation of the express server
app.use(
  cors({
    origin: [
      "https://examples.netlify.app",
      "http://localhost:3000",
    ],
    methods: ["GET", "POST", "DELETE"],
    credentials: true,
  })
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

/*
 * Handel user login
 */
app.post("/sign-in", (req, res) => {
  const { email, password } = req.body;

  sqlSelectAllUsers = "SELECT * FROM user_db WHERE email = ?";
  db.query(sqlSelectAllUsers, [email], (err, user) => {
    if (err) {
      res.send({ err: err });
    }

    if (user && user.length > 0) {
      // given the email check if the password is correct

      bcrypt.compare(password, user[0].password, (err, compareUser) => {
        if (compareUser) {
          //req.session.email = user;
          // create access token
          const accessToken = createAccessToken(user[0]);
          const refreshToken = createRefreshToken(user[0]);
          // create cookie and store it in users browser
          res.cookie("access-token", accessToken, {
            maxAge: 1000 * 60 * 30, // 30 min
            httpOnly: true, // hinder doing document.cookies as it will be httpOnly which will make it more safe
            secure: true,
            domain: "https://examples.netlify.app/",
            sameSite: "none",
          });
          res.cookie("refresh-token", refreshToken, {
            maxAge: 2.63e9, // approx 1 month
            httpOnly: true,
            secure: true,
            domain: "https://examples.netlify.app/",
            sameSite: "none",
          });

          // update refresh token in database
          const sqlUpdateToken =
            "UPDATE user_db SET refresh_token = ? WHERE email = ?";
          db.query(
            sqlUpdateToken,
            [refreshToken, user[0].email],
            (err, result) => {
              if (err) {
                res.send(err);
              }
              res.sendStatus(200);
            }
          );
        } else {
          res.send({ message: "Wrong email or password" });
        }
      });
    } else {
      res.send({ message: "Wrong email or password" });
    }
  });
});

app.listen(process.env.PORT || PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

客户端在 Netlify 上托管 React:

  export default function SignIn() {
  const history = useHistory();

  const handleSubmit = (event) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    // eslint-disable-next-line no-console
    axios
      .post(
        "https://example.herokuapp.com/sign-in",
        {
          email: data.get("email"),
          password: data.get("password"),
        },
        { withCredentials: "true" }
      )
      .then((response) => {
        //check if good response then give user a token for valid login
        if (response.data === "OK") {
          history.push("/");
          history.go(0);
        }
      });
  };
}


我不久前遇到了这个问题,简短的答案是: Heroku 不会为域设置 cookie*.herokuapp.com,因此如果您的应用程序依赖于 cookie,则无法将 Netlify 或其他托管用于您的前端。这是因为herokuapp.com已包含在 Mozilla 基金会的公共后缀列表中。

您对此无能为力。

如果你想尝试一些东西,我找到的解决方案(使用 Express 服务器和 Angular 前端)是将静态路由/文件夹添加到 Express 服务器,我将在其中放置通过构建 Angular 应用程序生成的文件(ng build --configuration production命令)。当你得到这些文件时,你git add他们并使用 Heroku CLI 进行推送。

通过这样做,Heroku 构建了 Express Server,并且您之前使用 Angular CLI 构建的文件都托管在 Heroku dyno 中。这样,cookie 就会被设置,因为不再是跨域,并且应用程序可以正常工作。

有关 Heroku 为何阻止此操作的更多信息,请参阅其文档的链接:https://devcenter.heroku.com/articles/cookies-and-herokuapp-com

编辑:忘记提及我的应用程序使用了 cookie,因为它实现了“本地策略”Passport图书馆。我没有编写任何代码来处理 cookie,但需要托管能够设置它们以使我的应用程序正常工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法使用 Netlify 和 Heroku 跨域设置/接收 cookie 的相关文章

随机推荐

  • 监控与锁定

    何时适合使用Monitor类或lockC 中线程安全的关键字 EDIT 从目前的答案看来lock是一系列调用的简写Monitor班级 锁调用简写到底是什么意思 或者更明确地说 class LockVsMonitor private read
  • 使用http查询字符串作为数据库对象node.js/express

    尝试使用node js express mongodb 我在用着 http localhost 3000 models save model 名称 等等等等 将测试 JSON 对象传递到快速路由 models save 以保存到 mongo
  • Nodejs 在同一时间运行代码一次

    我想在特定时间运行我的流程 但只运行一次 我应该使用 cron 作业 执行然后停止作业还是使用 setTimeout 哪个更好 Update 我在node cron模块中找到了它 我认为这比使用 setTimeout 更好 另一个关于日期的
  • Sonata 管理导出字段和集合字段

    我正在尝试制作用于导出的自定义列 但我无法访问子项 有可能这样做吗 我此时的代码如下所示 public function getExportFields return ID gt id Transaction number gt trans
  • 如何在 MKMapView 中的 MKAnnotation 上设置图像

    我正在开发一个聊天应用程序 我必须在地图上显示所有朋友及其图像 请提供实施指导 我使用了以下代码 MKAnnotationView mapView MKMapView mapView viewForAnnotation id
  • Microsoft Ribbon 未在 Designer 中呈现

    我正在使用 Microsoft Ribbon for WPF System Windows Controls Ribbon 和 VS2015 由于我从项目中删除了不必要的依赖项 例如动态数据显示等 与功能区无关的东西 它不再在设计器中正确呈
  • 如何在 Android 的服务中运行 CountDownTimer?

    我想要一个运行 CountDownTimer 的服务 并且在每个刻度中我想在 Activity 中显示倒计时 并在一段时间间隔后播放声音 所有过程在单个活动中都进展顺利 但在来电期间倒计时不起作用 这就是我想使用服务来执行此操作的原因 有谁
  • 元素上的 CSS 过渡留下线条

    我在绝对定位的元素上放置了悬停过渡 悬停状态将框阴影应用于标题元素 以模仿它填充该区域 以避免无法从属性集转换为自动的事实 仅在 Chrome 中 当反转过渡时 背景图像上会留下一堆油漆线 如下图所示 左侧第二个图块应用了悬停状态 NOTE
  • 查找最大值并显示 MS Access 中不同字段的相应值

    所以我在 查找最大值并显示 SQL Server 中不同字段的相应值 但我想更进一步 我想获取每个 ID 和相应类型的最新日期 而不仅仅是所有条目的绝对最大值 有什么建议么 ID Type Date 1 Initial 1 5 15 1 P
  • 对于没有托管库存的 WooCommerce 变体显示“有库存”通知

    我需要针对特定 情况的帮助 在 WooCommerce 中 如果为简单产品或变体启用了 管理库存 则会在产品页面 gt 中显示通知 例如 此示例 1 但是 如果不启用 管理库存 那么就没有通知 我觉得很遗憾 因为即使我不管理库存数量 我仍然
  • Rstudio 闪亮可折叠侧面板

    我想最大化可用屏幕宽度mainPanel一个 Rstudio 闪亮的网页 在我的网页中 sidePanel用于选择参数以可视化结果mainPanel 我想知道如何才能最大限度地利用可用空间mainPanel 例如 我想要一个 折叠 展开 选
  • 为什么在 WebKit 上使用 :before height 时对齐标记列表不同?

    Code http jsbin com maropaxivo 1 edit html css 输出 请参阅 Firefox 和 Chrome 浏览器的示例代码 为什么对齐标记列表不同 li before height 20px conten
  • Toolstrip WinForms .Net Core 的问题

    我正在 Net Core 中制作一个 Winforms 应用程序来学习一些基本的东西 这是一个简单的应用程序 我将一些文本从文本框写入文件 基本上像记事本 现在我想添加一个带有工具条按钮的工具条来创建新文件和一个工具条按钮来将文本保存到文件
  • 在 Java 中使用 switch 的问题

    我不明白为什么它总是返回 arg1 的值 我正在建造一个重量转换器 public double convert double arg1 int arg2 int arg3 arg1 amount arg2 from arg3 to doub
  • signalR 中的第一个任意消息没有 messageID?

    我写了这个简单的代码 当连接时 应该产生 第一的 欢迎 3 条消息 计时器 这是代码 int i 0 protected override Task OnConnected IRequest request string connectio
  • 示例 Blazor 项目中的计数器状态可以在页面切换之间保留吗?

    在服务器端 Blazor 和 WebAssembly Blazor 项目的默认示例项目中 每次在页面之间移动时 计数器示例都会重置为 0 但是 在 ASP NET React 示例项目中 计数器不会在页面切换之间重置 有没有办法让像 Cou
  • 如何使用 kotlin 协程进行 Firestore 查询

    我创建了一个应用程序Kotlin and Firebase Firestore 现在我需要实现协程 因为主线程上有很多工作 但我也是一个初学者 所以这对我来说是新的东西 我看过一些关于此的教程 但没有找到完整的教程Firestore与协程
  • 隐藏多个div,默认显示1,并根据链接点击在它们之间切换(显示/隐藏)?

    我知道显示 隐藏的事情已经在堆栈上被覆盖得很厉害 但我只是找不到适合我的解决方案 抱歉 我已经尝试了几种我发现的 JS jQuery 解决方案 但无法完全让其中一个按照我想要的方式运行 我有许多内容非常相似的 div 内容根据所选版本略有变
  • Android GCM 服务器已发送但 GCM 未推送到设备

    我正在手机上测试 GCM 2 3 6 安卓 清单文件 MainActivity First 和 Second 活动不执行任何操作 它们用于其他测试目的 不会干扰 GCM
  • 无法使用 Netlify 和 Heroku 跨域设置/接收 cookie

    我遇到了无法在浏览器中设置 cookie 的问题 因为客户端托管在 Netlify 上 服务器托管在 Heroku 上 它在本地主机上运行良好 所以看起来它现在与跨域有关 阅读了多篇关于此的文章后 似乎这可能与 cors 或我如何设置 co