Browser is not sending the cookie with fetch, allthough server and frontend have the same ip address (but different ports)

54 Views Asked by At

Ialready tried many things, but the browser still refuses to set the Cookie header on any request I make in the frontend. Both server and frontend running on my local machine.

I created a hosts entry and enabled port forwarding.

So api-v3-dev:5177 is the frontend and api-v3-dev:3000 is the backend.

I dynamically set the Access-Control-Allow-Origin to the request's origin.

After successfull login, I see a responses header like

set-cookie: token=eyJoZTUiLCJpZCI6; HttpOnly; SameSite=Lax
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://api-v3-dev:5177
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Set-Cookie, Cookie, Origin, X-Requested-With, Bearer, Accept

When I do another fetch request with like:

 const requestOptions = {
        method: 'GET',
        credentials: 'include'
    };
 fetch('http://api-v3-dev:3000/whoami', requestOptions);

Since it is locally, I cannot set Secure & SameSite=None.

But everthing I read about cookies and sameSite tells, that it is not like the Origin in Cors and it indeed treats both different subdomains and different ports as the same site, so it should also work with sameSite=Lax for http connections.

1

There are 1 best solutions below

1
Heiko Theißen On

Your browser receives the token=eyJoZTUiLCJpZCI6 cookie with the HTTP response but does not store it, because it violates the following validity requirement:

The domain of the cookie must be .local or a subdomain of a public suffix (see http://publicsuffix.org/ --also known as an extended Top Level Domain).

The hostname api-v3-dev defined in your hosts file ends with neither .local nor a public suffix. (Nor is it localhost, which would also work.)

And since the cookie is not stored in the browser, it is not sent with any subsequent request either.

Strangely, if a cookie is received with an HTTPS response, it is set even if the rule given above is violated. At least that is the behavior I observed with Google Chrome.