corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.readthedocs.io/en/latest/index.html
MIT License
889 stars 140 forks source link

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' #200

Closed Syntaf closed 7 years ago

Syntaf commented 7 years ago

Not sure why I'm getting this error when trying to allow CORS on my flask app. Here's my server:

#library imports
from flask import Flask
from flask_cors import CORS, cross_origin

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'

@app.route('/img', methods=['POST'])
def image_upload():
    if not request.json:
        abort(400)
    print(request.json)
    return jsonify('working')

if __name__ == "__main__":
    app.run(host= "0.0.0.0", debug=True, port = 5000, threaded=True)
    print("Running dev server on port 5000")

Now on my frontend, when I attempt to make a POST request to /img, I get the error in the title. The full error is:

XMLHttpRequest cannot load http://0.0.0.0:5000/img. 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:8080' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Syntaf commented 7 years ago

Update: Adding the following code works, is there a way to do this with flask-cors so I don't need to ways of allowing cross-origin?

@app.after_request
def after_request(response):
  response.headers.add('Access-Control-Allow-Origin', 'http://localhost:8080')
  response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
  response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
  response.headers.add('Access-Control-Allow-Credentials', 'true')
  return response
corydolphin commented 7 years ago

Sorry for the delay!

  1. You need to pass "supports_credentials=True" or "CORS_SUPPORTS_CREDENTIALS"=True in your config.
  2. Your "CORS_HEADERS" config is incorrectly spelled (and unnecessary, since the default is to allow all headers). The correct config option is "CORS_ALLOW_HEADERS" and "CORS_EXPOSE_HEADERS"
ghost commented 6 years ago

@corydolphin I have the same error. I have built na application and If I test request using Postman or Insonia it works normally, the application receive the requests and store the data in the session / database, but if I try to make a request from a React application using Axios I receive an error and the application doesn't receive any request or store data.

Error :

Failed to load 127.0.0.1:5000/logout : 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 ' localhost:8080 ' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Flask application config :

# Imports

from flask import Flask

from flask_cors import CORS

# Cors

config = {
  'ORIGINS': [
    'http://localhost:8080',  # React
    'http://127.0.0.1:8080',  # React
  ],

  'SECRET_KEY': '...'
}

# App

app = Flask('Test')

CORS(app, resources={ r'/*': {'origins': config['ORIGINS']}}, supports_credentials=True)

Request in React :

axios({
  method: 'post',
  url: `127.0.0.1:5000/logout`,
  headers: {Authorization: `Bearer ${this.state.login.access_token}`},
  withCredentials: true // True otherwise I receive another error
}).then(response => {
  console.log('Logout ', response);
})

I have also research but I don't know how to solve this.

Obs ¹ : I'm using server side session (Flask Session)

Obs ² : The other error is a 500. It happens because I try to get something from session to make the logout, but the attribute is not found in session (if I make the request with the tool I mentioned, it works fine).

jonthemango commented 4 years ago

@Sphinxs Were you able to rectify the issue? I have the same error and setup.

ghost commented 4 years ago

Yes, besides withCredentials: true I have also set crossorigin: true in the Axios request, and in my Flask application I have mapped the 0.0.0.0, that listen to all local network interface, i.e, localhost (aka, 127.0.0.1).

If I remember well I have also added other parameter in the CORS(...) call, I don't remember well which one, I recommend that you read the parameters of CORS and the section about how to specify a Regex pattern.

ghost commented 4 years ago

Sorry for the delay!

1. You need to pass "`supports_credentials=True`" or "CORS_SUPPORTS_CREDENTIALS"=True in your config.

2. Your "CORS_HEADERS" config is incorrectly spelled (and unnecessary, since the default is to allow all headers). The correct config option is "CORS_ALLOW_HEADERS" and "CORS_EXPOSE_HEADERS"

Please can you add something in the documentation that explains how to do it? I tried adding CORS_SUPPORTS_CREDENTIALS = True to the documentation and nothing happens. I don't understand why flask-cors does not work with axios by default, and why there is nothing in the documentation which provides a minimum working configuration for flask-cors. If the library does not even allow the application to handle the preliminary OPTIONS request, what is the point of it?

emilJS777 commented 3 years ago

I have the same problem too, who knows if there are other alternatives like a flask-cors, but to work fine?

l1tecoding commented 2 years ago

I have the same problem too, who knows if there are other alternatives like a flask-cors, but to work fine?

CORS_ALLOW_ORIGIN="*,*"
CORS_EXPOSE_HEADERS="*,*"
CORS_ALLOW_HEADERS="content-type,*"
cors = CORS(app, origins=CORS_ALLOW_ORIGIN.split(","), allow_headers=CORS_ALLOW_HEADERS.split(",") , expose_headers= CORS_EXPOSE_HEADERS.split(","),   supports_credentials = True)
emilJS777 commented 2 years ago

frankly, the delete request does not work.  but the rest of the requests are processed fine. thanks in advance  

Воскресенье, 7 ноября 2021, 20:13 +04:00 от Givanchi @.**>:     I have the same problem too, who knows if there are other alternatives like a flask-cors, but to work fine? CORS_ALLOW_ORIGIN="," CORS_EXPOSE_HEADERS="," CORS_ALLOW_HEADERS="content-type," cors = CORS(app, origins=CORS_ALLOW_ORIGIN.split(","), allow_headers=CORS_ALLOW_HEADERS.split(",") , expose_headers= CORS_EXPOSE_HEADERS.split(","), supports_credentials = True) — You are receiving this because you commented. Reply to this email directly, view it on GitHub , or unsubscribe . Triage notifications on the go with GitHub Mobile for iOS or Android .    

Emil Hambardzumyan  

InesIvanova commented 2 years ago

This comment is not directly related to the question, but it is a subcase of CORS issues. I have seen this error many times before, so I will share it and hope it will help someone. If you are using flask-cors, even with the basic setup (not recommended for production, you have to restrict the requests)

`from flask import Flask from flask_migrate import Migrate from flask_restful import Api

from db import db from resources.routes import routes from flask_cors import CORS

app = Flask(name) db.init_app(app) app.config.from_object("config.DevelopmentConfig") migrate = Migrate(app, db) CORS(app)`

It will work perfectly fine. However you can still see errors like this in the front-end app console: Access to XMLHttpRequest at 'http://127.0.0.1:5000/login' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

In this case, you should check the URL itself and the missing trailing slash. For example - FE makes a request to http://127.0.0.1:5000/login but the backend endpoint is http://127.0.0.1:5000/login/ (assuming you have not done any specific configurations in the app) Once the URL is corrected it will work well