首页 > 解决方案 > 跨站点 cookie 的问题:如何将 cookie 从后端设置到前端

问题描述

我目前正在开发我的第一个 web 应用程序,前端React使用FastAPI.

我正在尝试与 Chrome 一起测试它——看看前端是否对后端进行了正确的 API 调用,并显示结果。我一直在使用 cookie 时遇到问题,我需要帮助。提前为这篇长文道歉——过去几天我浏览了很多资源,在这一点上,我不确定什么是相关的,什么是不相关的。

app = FastAPI()

origins = [
    "http://localhost:8080"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


情况:前端GET向后端发出请求http://127.0.0.1:8000/api/abc,后端设置了一个cookie。

/*====================
尝试1:
使用以下后端代码设置cookie:

response.set_cookie(key="abcCookieKey", value="abcCookieValue")

GET使用以下前端 JS 代码发出请求:

fetch('http://127.0.0.1:8000/api/abc', {
            method: 'GET',
            credentials: 'include',
        })

尝试 1 的结果:
ConsoleChrome 的选项卡上,我收到以下警告:

A cookie associated with a cross-site resource at http://127.0.0.1/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

set-cookie在网络选项卡上,我在检查响应标头时收到以下消息:

This Set-Cookie was blocked because it has the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.

=====================*/


...所以我做了一些研究,然后想出了

/*====================
尝试2:
使用以下后端代码设置cookie:

response.set_cookie(key="abcCookieKey", value="abcCookieValue", samesite="none", secure=True)

GET使用相同的前端 JS 代码发出请求。

尝试 2 的结果:
ConsoleChrome 的选项卡上,我收到与尝试 1 完全相同的警告,即使响应标头具有set-cookiewith Samesite=none; Secure。此外,标题有以下警告

This Set-Cookie was blocked because it had the "Secure" attribute but was not received over a secure connection.

=====================*/


..所以我尝试使用https并提出:

/*====================
尝试 3: 一切都与尝试 #2 相同,除了在我的 JS 获取代码中,我使用fetch('https://127.0.0.1:8000/api/abc ...
然后我收到以下警告我的后端运行uvicornWARNING: Invalid HTTP request received.

=====================*/

问题:

  1. 我错过了尝试#2的东西吗?肯定有一种简单的方法可以从后端到前端设置 cookie 而不必担心 https 吗?
  2. 如果我别无选择,只能使用https,如何在本地运行可以访问的后端服务器https?我所做的研究使它看起来像是一个复杂/耗时的过程。(但是,公平地说,我对 web-dev/all things network 的理解非常有限)。

标签: reactjsgoogle-chromecookiesfastapisamesite

解决方案


我将尝试给出这个概念。

首先请知道我使用的是从开发的后端和从开发SailsJS的前端以及AngularJS从使用开发的连接到后端的应用程序Angular9

我正在为前端(CMS)使用仅限 http 的 cookie,以授予向已登录用户添加内容的权限。身份验证成功后,将为他们设置仅限 HTTP 的 cookie。

请注意,http cookie 有一个棘手的部分,并且后端和前端都提供不同的 URL,就像在呈现的场景中一样。

要点:

  1. 因此,在开发过程中,您必须将后端和前端托管在相同的 IP 下。前任。我的后端:192.168.8.160:1337,前端:192.168.8.160:81。不同的端口相同的ip。

  2. 这不是投入生产时的情况,您可以拥有任何域:)

  3. 您必须在后端允许 CORS 并将您的前端 ip:port 置于可接受的来源之下。

  4. 实施,你必须确定你的环境,在我的情况下,


if (sails.config.environment === 'development'){
  res.setHeader('Set-Cookie',[`token=${token};  Path=/;HttpOnly; maxAge=86400000;SameSite=false;`]);
} else {
  res.setHeader('Set-Cookie',[`token=${token};  Path=/;HttpOnly; maxAge=86400000;SameSite=None;Secure=true;`]);
}


请注意,在开发环境中的上述代码中,您需要SameSite=false因此需要具有相同的 ip,因为我们不能拥有SameSite=None,因为它需要拥有Secure=true,然后需要 HTTPS。在开发模式下实现它会很头疼。

就是这样的人。如果你做对了,你就可以做到这一点。


推荐阅读