Javascript Express+;反应:CSRF Cookie在生产中未定义,在本地工作

Javascript Express+;反应:CSRF Cookie在生产中未定义,在本地工作,javascript,reactjs,express,cookies,Javascript,Reactjs,Express,Cookies,我在Heroku上托管我的expressAPI,在Netlify上托管我的客户端。当我在本地尝试我的注册路径时,我的cookie被定义并且该路径工作。然而,当它在生产中时,cookie总是返回未定义的,并且MyAPI超时 请注意,正在从后端成功发送cookie。我可以在开发工具中查看它。此外,cookies get()返回一个空对象 我正在使用Js cookie 我在盖茨比使用js cookie。我在express中使用CSURF作为cookie 后端: //CSURF Config app.u

我在Heroku上托管我的expressAPI,在Netlify上托管我的客户端。当我在本地尝试我的注册路径时,我的cookie被定义并且该路径工作。然而,当它在生产中时,cookie总是返回未定义的,并且MyAPI超时

请注意,正在从后端成功发送cookie。我可以在开发工具中查看它。此外,cookies get()返回一个空对象

我正在使用Js cookie

我在盖茨比使用js cookie。我在express中使用CSURF作为cookie

后端:

//CSURF Config
app.use(csurf({ cookie: true }));


//Route that generates CSRF Cookie
app.get("/getToken", (req, res) => {
    res.cookie("XSRF-TOKEN", req.csrfToken());
    res.end();
  });
前端:

我包括了整个注册功能。请注意,这是两个端点调用,一个用于检索cookie,另一个用于创建用户记录

  userSignUp = async (email, password, resetForm) => {
    console.log("THis is a test of the emergency..")
    await fetch(process.env.API + "getToken", {
      mode: "cors", // no-cors, cors, *include
      cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
      credentials: "include", // include, *include, omit
      headers: {
        "content-type": "application/json",
      },
      method: "GET",
    })
    const token = Cookies.get("XSRF-TOKEN")
    alert(Cookies.get("XSRF-TOKEN"))
    const data = await fetch(process.env.API + "signUp", {
      body: JSON.stringify({ email: email, password: password }),
      mode: "cors", // no-cors, cors, *include
      cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
      credentials: "include", // include, *include, omit
      headers: {
        "content-type": "application/json",
        "csrf-token": token,
      },
      method: "POST",
    }).catch(error => this.setState({ isError: true }))
    if (data.ok) {
      console.log(data.ok)
      data.json().then(content => {
        console.log(content)
        this.props.changeAuth(content.authStatus)
        this.props.setCategories(content.user.categories)
        this.props.getEvents(content.user.events)
        resetForm()
      })
    } else {
      this.setState({
        isError: true,
      })
    }
  }
…在生产中,cookie总是返回未定义的

一个可能的原因可能是您在生产中使用HTTPS(应该是这种情况),而浏览器会忽略CSRF cookie,因为它没有设置为安全cookie。要解决此问题,请在生产中使用安全cookie,在开发中使用非安全cookie

附加说明
要使第一个cookie安全,请替换此代码

app.use(csurf({ cookie: true }));
res.cookie("XSRF-TOKEN", req.csrfToken());
因此:

app.use(csurf({
  cookie: {
    httpOnly: true,
    secure: !devModeFlag
  }
}));
res.cookie("XSRF-TOKEN", req.csrfToken(), { secure: !devModeFlag });
httpOnly
设置确保客户端上的JS不能接触此cookie,这有助于提高安全性。布尔
devModeFlag
变量在开发中应设置为true,在生产中应设置为false

要使第二个cookie安全,请替换此代码

app.use(csurf({ cookie: true }));
res.cookie("XSRF-TOKEN", req.csrfToken());
因此:

app.use(csurf({
  cookie: {
    httpOnly: true,
    secure: !devModeFlag
  }
}));
res.cookie("XSRF-TOKEN", req.csrfToken(), { secure: !devModeFlag });

如果前端域和服务器域不同,cookie将无法工作

您可以将所有请求重定向到前端域到后端域的路径(例如
/api/

要设置代理,您可以使用以下配置在发布目录(例如,
public
)中创建一个
\u重定向
文件:

/api/*  https://<server-url>:<server-port>/:splat 200
/api/*https://:splat 200

最后,将所有HTTP请求发送到该前端路径(例如
https:///api/users
)而不是后端URL,以确保Cookie正常工作。

您的网页URL和服务器URL是什么?它们不同。。。一个是heroku随机url,另一个是netlify url注意,它在本地主机端口3000(服务器)和本地主机端口8000(客户端)上工作。而且服务器正在设置cookies。我可以在chrome开发工具中看到它们。我尝试了这些更改,但无法让它们正常工作。更有趣的是,cookies正在发送过来,我可以在开发工具中看到它们。当我执行cookies.get()时,它返回一个空对象。我的想法是,要么Netlify以一种奇怪的方式处理cookie,要么js cookie包或我使用它的方式出了问题。另一个问题是,您使用
凭据:“在客户端上包括”
,而不是标题。这个MDN页面说“服务器(使用Access Control Allow Credentials标头)和客户端(通过为XHR、Fetch或Ajax请求设置凭据模式)都必须指示它们选择包含凭据”。我假设客户端JS是从Netlify下载的,而不是从Heroku服务器下载的。不过,我可以在我的开发控制台中看到cookie,并且它们设置正确。我想它仍然会被设置,但是
cookies.get()
只会尝试从同一域获取cookies。试试我的解决方案,看看是否有效。我很快就会试试。非常感谢。