3

I have a backend Flask app running on localhost:3000 and a React front-end app running on localhost:5000. In my backend app I am using Flask's 'Response.set_cookie' to set a cookie:

resp = make_response({}, 200)
resp.set_cookie('my_cookie_name', 'my_val', max_age=604800, domain='127.0.0.1', samesite='Lax', secure=None, httponly=None)

I am also allowing cross-origin for all responses in my flask app as follows:

# Child class of Flask to override some features
class TailoredFlask(Flask):

  # Override make_response
  def make_response(self, rv):

    # Call default version from partent
    resp = super().make_response(rv)

    # Add CORS header to every response
    resp.headers["Access-Control-Allow-Origin"] = "*"
    resp.headers["Access-Control-Allow-Methods"] = "GET,POST,OPTIONS,HEAD"
    resp.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    return resp

My client accesses my flask cookie endpoint with a call to fetch.

In the Chrome dev tools I can see that the cookie is sent with the HTTP response from my backend. It is visible when on the Network->Cookies tab when I select the request to my backend. However, if I go to the Application tab in the dev tools, my cookie is not there.

It seems like chrome is silently discarding my cookie. I have seen several simiar issues here on SO but none of them seem to explain what is going on or provide a solution to my issue.

I'm also confused about the cookie options. There is a 'domain' option which I've read is to allow cross domain operation for the cookie. However, everything is running on localhost so I feel that I shouldn't need this unless the port is causing issues. However, I have also read that the port should not be included in the cookie 'domain' field.

If anyone can help to explain this to me I would greatly appreciate it because I'm just going round in circles with this stuff.

One more thing to note: I am pointing the browser at 'localhost', but the API call to my backend and the cookie domain both use '127.0.0.1', since I've read elsewhere that the 'domain' field must have at least two dots in it. (I don't have a choice in the browser URL since I am using AWS cognito login UI to redirect to my app after login. Cognito allows http for 'localhost', but only allows https for '127.0.0.1' so I have to use 'localhost' for development.) Could the missmatch between the browser url and cookie domain be causing this issue? Or is there something else that I'm missing?

SleepyJack
  • 167
  • 5
  • is there any error in the browser console? – Ashish May 21 '20 at 10:59
  • @Ashish No I'm not seeing any error in the console. I have tried reproducing the issue by creating a simple flask app that sets a cookie with 'domain' set to '127.0.0.1' and then accessing it via 'localhost:5000'. In that case in the 'Network'->'Cookies' dev tools tab, the response cookie is highlighted in yellow with the message "This set-cookie's domain attribute was invalid with regards to the current host url" In my actuall app I'm not getting any error from the browser, it just silently discards the cookie. Thanks – SleepyJack May 21 '20 at 12:04
  • Clients hosted in different ports that flask's, all the request from clients are like new requests. So, it won't work. – ngShravil.py May 21 '20 at 14:58
  • @ngShravil.py I wondered about that, but saw [this](https://stackoverflow.com/questions/1612177/are-http-cookies-port-specific) post from which I understood that the port is not relevant to the cookie domain. In any case, is it not quite common to run front-end and back-end at different localhost ports during development? How do people normally get around this? – SleepyJack May 22 '20 at 18:06

1 Answers1

2

Ok, so I think I now understand what's going on here, although I don't think there's a fix for my specific problem. As described in this thread browsers (including Chrome) will not allow a domian of 'localhost' within a cookie (I just wish there was a message in the console or something to indicate why the cookie is not being saved, rather than a silent fail!)

There are various suggestions for workarounds, such as using '.app.localhost' to access the application. Unfortunately this is not an option for me as I am redirecting to my front-end app from AWS Cognito, and the only domain that is supported with HTTP (rather than HTTPS) is 'localhost'. Variants such as '.app.localhost' or '127.0.0.1' are not allowed.

SleepyJack
  • 167
  • 5