跨站点Cookie的问题:如何设置后端到前端的Cookie [英] issue with cross-site cookies: how to set cookie from backend to frontend

查看:673
本文介绍了跨站点Cookie的问题:如何设置后端到前端的Cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently developing my first webapp, frontend with React and backend with FastAPI.

我正在尝试与Chrome一起进行测试-查看前端是否对后端进行了正确的API调用,并显示结果.我在使用Cookie时遇到了问题,希望获得帮助.很长一段话要提前道歉–在过去的两天里,我一直在浏览许多资源,而现在我不确定什么是相关的,什么是不相关的.

I'm trying to test it out jointly with Chrome-- see if the frontend makes the correct API calls to backend, and display the results. I've been having problems with cookies, and I'd like help. Apologies in advance for the long post – I've been going through many resources past couple of days, and at this point I'm unsure what's relevant and what's not.

  • localhost:8080
  • 上的前端
  • http://127.0.0.1:8000
  • 上的后端
  • 使用以下 FastAPI 后端代码对CORS进行正确设置(我相信):
  • Frontend on localhost:8080
  • Backend on http://127.0.0.1:8000
  • Proper settings for CORS (I believe) with the following FastAPI backend code:
app = FastAPI()

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

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


情况:前端对后端的 http://127.0.0.1:8000/api/abc 发出 GET 请求,后端会设置一个Cookie.


Situation: Frontend makes a GET request to http://127.0.0.1:8000/api/abc on backend, the backend sets a cookie.

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

/*====================
Attempt 1:
set cookie with the following backend code:

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

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

and make the GET request with the following frontend JS code:

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

尝试1的结果:
在Chrome的控制台标签上,我收到以下警告:

Result with attempt 1:
on the Console tab of Chrome, I get the following warning:

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 响应标头时,我收到以下消息:

and on the network tab I get the following message when examining the set-cookie response header:

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.

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

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


...所以我做了一些研究,并提出了


...so I do some research, and come up with

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

/*====================
Attempt 2:
set cookie with the following backend code:

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

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

and make the GET request with the same frontend JS code.

尝试2的结果:
在Chrome的 Console 标签上,即使响应标头具有带有 Samesite的 set-cookie ,我仍收到与尝试1完全相同的警告.= none;安全.此外,标头中还显示以下警告

Result with attempt 2:
on the Console tab of Chrome, I get the exact same warning as from attempt 1, even though the response header has a set-cookie with Samesite=none; Secure. Additionally, the header has the following warning

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

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

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


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

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

/*====================
Attempt 3: Everything the same as attempt #2, except in my JS fetch code, I use fetch('https://127.0.0.1:8000/api/abc ...
and then I get the following warning on my backend running with uvicorn: WARNING: Invalid HTTP request received.

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

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

问题:

  1. 我在尝试2时缺少什么吗?当然,必须有一种简便的方法来设置从后端到前端的cookie,而不必担心https?
  2. 如果我别无选择,只能使用 https ,如何在本地运行可以通过 https 访问的后端服务器?我所做的研究似乎是一个复杂/耗时的过程.(但是,公平地说,我对Web-dev/万物网络的了解非常有限.)
  1. am I missing something with attempt #2? surely there must be an easy way to set a cookie from backend to frontend without worrying about https?
  2. if I don't have a choice but to use https, how do I locally run a backend server that can be accessed with https? The research I did made it seem like it was a complicated/time-consuming process. (But, to be fair, my understanding of web-dev/all things network is very limited).

推荐答案

我将尝试给出这个概念.

I will try to give the concept.

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

First please know that I'm using a Backend which is developed from SailsJS and a Frontend which is developed from AngularJS and Apps that connect to backend which are developed from using Angular9.

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

I am using http only cookie for the frontend (a CMS) to grant permission to add content to users that are logged in. HTTP only cookie will be set to them on authentication success.

请注意,http cookie有一个棘手的部分,后端和前端都提供不同的URL,就像在所展示的场景中一样.

Please note that there is a tricky part to http cookies and backend and frontend both serve different URLs just like in the scenario presented.

点:

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

  1. So when in development you have to host your backend and frontend under same IP. ex. my backend : 192.168.8.160:1337, frontend: 192.168.8.160:81. different ports same ip.

在生产环境中,这不是场景,您可以拥有任何域:)

this is not the scenario when it goes to production you can have any domain :)

您必须在后端允许CORS,并且将前端ip:port设置为可接受的来源.

you have to allow CORS in backend and have your frontend ip:port under accepted origins.

实施中,您必须确定您的环境,

Implementation, you have to identify your environment, in my case,


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.在开发模式下实现它会很头疼.

Please note in above code in development environment you need SameSite=false therefore you need to have the same ip because we cannot have SameSite=None because it would require to have Secure=true and it would then require HTTPS. It would be a headache to achieve it in development mode.

就是这样.如果您做对了,就可以实现这一目标.

That's it folks. If you get this right you can achieve this.

这篇关于跨站点Cookie的问题:如何设置后端到前端的Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆