0

I'm running a React frontend and a Flask backend. I don't understand anything.

Let's talk CORS. CORS is Cross-Origin Resource Sharing. So why does Chrome complain about CORS when I'm running both my frontend and my backend on the same host?

So I enable CORS on my Flask backend, and continue on my merry way.

I'm not stupid so I'm like, how do I keep my user's data if they accidentally refresh or close the page? Well luckily Flask has cookies built in with session. So I go ahead and store the important things in session, and in componentDidMount, I try to fetch some important things. But after refreshing, Flask forgets the session, and my fetch returns no useful data.

I tried to look this up for a while, and I see interesting looking things, like the credentials parameter to fetch. If I write in {credentials: "include"}, according to the docs:

Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.

So ostensibly, this should solve my problem and somewhat resolve my confusion, but, of course, no such luck:

Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access.

Please, help me understand what's happening, and how I can fix it.

I'll keep doing my research.

Academiphile
  • 1,134
  • 1
  • 9
  • 21

2 Answers2

2

In short:

  1. Your server should say it support credentials. support_credentials=True in Flask which results in Access-Control-Allow-Credentials: true Header.
  2. Your frontend should include credentials in request: {credentials: "include"}
  3. Your server should return not wildcarded Access-Control-Allow-Origin ie http://foo.example instead of *.

It's best to use browser's dev tools to troubleshoot it.

Have a look here for bigger explanation: https://stackoverflow.com/a/7189502/803174

Kangur
  • 7,175
  • 3
  • 22
  • 27
1

So I found a solution, but I'm willing to accept an answer that clearly explains what's going on.

My solution was adding supports_credentials=True into my Flask app, such that the line of code looks like:

CORS(app, supports_credentials=True)

I can then add credentials: 'include' into my fetch request, and cookies seem to be successfully stored.

Academiphile
  • 1,134
  • 1
  • 9
  • 21
  • Unless your front-end and back-end share the same protocol, host and port, requests will get flagged by CORS. – lux Aug 23 '18 at 03:53
  • Setting 'supports_credentials=True' causes your Flask app to set the value of the 'Access-Control-Allow-Credentials' response header to 'true', which eliminates the error cited in the question. If the value of the 'Access-Control-Allow-Credentials' response header isn’t 'true', then your browser blocks your frontend JavaScript code from sending your request. (The error message cited in the question is for CORS preflight OPTIONS request that the browser automatically on its own sends before trying the request from your code. If the preflight fails, your browser stops right there.) – sideshowbarker Aug 23 '18 at 03:54