I'm currently developing my first webapp, frontend with React
and backend with FastAPI
.
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
backend code:app = FastAPI()
origins = [
"http://localhost:8080"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Situation: Frontend makes a GET
request to http://127.0.0.1:8000/api/abc
on backend, the backend sets a cookie.
/*====================
Attempt 1:
set cookie with the following backend code:
response.set_cookie(key="abcCookieKey", value="abcCookieValue")
and make the GET
request with the following frontend JS code:
fetch('http://127.0.0.1:8000/api/abc', {
method: 'GET',
credentials: 'include',
})
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.
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
/*====================
Attempt 2:
set cookie with the following backend code:
response.set_cookie(key="abcCookieKey", value="abcCookieValue", samesite="none", secure=True)
and make the GET
request with the same frontend JS code.
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 I try to use https
and come up with:
/*====================
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.
====================*/
Questions:
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).While it's possible to create cookies in the browser with document. cookie , most of the times it's responsibility of the backend to set cookies in the response before sending it to the client.
You can't access cookies from a different path - otherwise it would be a security hole.
In the address bar enter the following URL 'chrome://flags/#same-site-by-default-cookies' Set the flags 'SameSite by default cookies' and 'Cookies without SameSite must be secure' to 'Enabled' and restart the Chrome browser. Test all applicable flows that involve cookies, to determine if there is an impact.
To set a cookie in REST API response, get the Response reference and use it's cookie() method.
I will try to give the concept.
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
.
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.
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.
Points:
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 :)
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;`]);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With