首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用Netlify和Heroku设置/接收跨域cookie。

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

Stack Overflow用户
提问于 2022-02-07 21:35:33
回答 3查看 2K关注 0票数 3

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

在阅读了这方面的多篇文章之后,它似乎与cors有关,或者我是如何设置cookie的。

我在某个地方读到,在设置cookie时,它可能会帮助添加secure: truesameSite: "none",所以我添加了它们,但没有帮助。在设置cookie时,我也尝试过将domain添加到cookie中,但不幸的是,它也没有帮助。

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

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

托管在Heroku上的带有节点js (快递)的服务器端

代码语言:javascript
复制
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的客户端

代码语言:javascript
复制
  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);
        }
      });
  };
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-02-10 20:15:33

好的,我终于解决了,我想我应该在这里写下我是怎么做到的。

尽管这似乎是一种普遍的信念,但实际上,在Heroku和Netlify之间发送cookie是可能的。

我认为,在更改设置cookie的方式时,我同时添加了domainsameSitesecure,因此没有测试没有domain的场景。删除domain之后,就可以在heroku中设置cookies,这使得它能够在netlify中工作。因此,它的登录工作,但有两个主要的问题与此。Cookies将随机停止工作,一旦Heroku进入空闲模式(在免费版本上似乎是这样),它将使应用程序和cookie陷入混乱,迫使我重新启动所有dynos。因此,尽管似乎可以通过Netlify和Heroku来完成这一任务,但我不建议跨域使用cookie。(我也读过使用sameSite:none可能会增加CSRF攻击的风险,因此在设置cookie时使用并不理想)

最后的解决方案:--我开始在heroku上使用代理等在heroku上托管客户机和服务器。

现在,曲奇的工作方式,他们应该和网站已经启动和运行!

票数 1
EN

Stack Overflow用户

发布于 2022-02-07 23:26:32

不久前,我遇到了这个问题,简短的回答是: Heroku不会为域*.herokuapp.com设置cookie,因此,如果应用程序依赖cookie,就不可能使用Netlify或其他主机。这是因为herokuapp.com包含在Mozilla的公共后缀列表中。

你对这件事没什么可做的。

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

通过这样做,Heroku构建了Express Server,而预先使用角CLI构建的文件都托管在Heroku dyno中。这样,cookie就会被设置,因为它不再是跨域的,而且应用程序也能工作。

关于Heroku为什么在文档的这个链接中阻止这一点的更多信息:https://devcenter.heroku.com/articles/cookies-and-herokuapp-com

编辑:忘了提到我的应用程序使用了cookies,因为它实现了Passport库的“本地策略”。我没有编写任何代码来处理cookie,但需要主机来设置它们才能使我的应用程序正常工作。

票数 4
EN

Stack Overflow用户

发布于 2022-04-10 13:05:10

解决方案可以在:Cross-Domain Session Cookie (Express API on Heroku + React App on Netlify)下面找到。

秘诀是添加快速会话的会话设置:

代码语言:javascript
复制
    app.use(
      session({
        secret: process.env.SESSION_SECRET || 'Super Secret (change it)',
        resave: true,
        saveUninitialized: false,
        cookie: {
          sameSite: process.env.NODE_ENV === "production" ? 'none' : 'lax', // must be 'none' to enable cross-site delivery
          secure: process.env.NODE_ENV === "production", // must be true if sameSite='none'
        }
      })
   );

检查并为我工作!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71025703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档