跨站点 cookie 的问题:如何设置从后端到前端的 cookie

IT技术 reactjs google-chrome cookies fastapi samesite
2021-05-01 15:13:10

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

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

  • 前端开启 localhost:8080
  • 后端开启 http://127.0.0.1:8000
  • 使用以下FastAPI后端代码正确设置 CORS(我相信)
app = FastAPI()

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

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


情况:前端GEThttp://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-cookie带有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 的理解非常有限)。
3个回答

我会尝试给出这个概念。

首先请知道我使用的是从开发的后端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。在开发模式下实现它会很头疼。

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

您可以通过转到“chrome://flags”并禁用“没有 SameSite 的 Cookie 必须是安全的”来完全禁用此功能。但是,这将对所有站点禁用它,因此当您不进行开发时,它的安全性会降低。

删除通配符,因为通配符是不允许的allow_credentials=True

app.add_middleware(
  CORSMiddleware,
  allow_origins=['http://localhost:8080'],
  allow_credentials=True,
  allow_methods=["GET", "POST", "OPTIONS"], /* include additional methods as per the application demand */
  allow_headers=["Content-Type","Set-Cookie"], /* include additional headers as per the application demand */
)

设置samesitenone同时设置cookie(现代浏览器都需要它):

/* `secure=True` is optional and used for secure https connections */
response.set_cookie(key='token_name', value='token_value', httponly=True, secure=True, samesite='none')

如果客户端正在使用 Safari,请Prevent cros-site trackingPreferences. 而已!