corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.corydolphin.com/
MIT License
873 stars 140 forks source link

Getting CORS preflight error even with flask cors initialized #292

Open ryanbrwr opened 3 years ago

ryanbrwr commented 3 years ago

Hey guys, I've been trying to get flask_cors to work for over two weeks now, so thought that I would write an issue.

Here's what is in the init.py file

app = Flask(__name__, static_url_path='/static')
app.config.from_pyfile('config.py')

cors = CORS(resources={
    r'/*': {
        'origins': [
            'http://localhost:8080'
        ]
    }
})

cors.init_app(app)

The error that I'm getting is:

login?redirectNotebook=rose.intro:1 Access to XMLHttpRequest at 'http://localhost:5000/users' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Went into the library to poke around and it looks like the after request isn't being called. The backend is running on localhost:5000 and the frontend is running on localhost:8080, any help would be greatly appreciated!

shrhawk-entertainer commented 3 years ago

@ryanbrwr did you find any solution?

ryanbrwr commented 3 years ago

@shrhawk-entertainer No unfortunately I never found a solution and I am currently having to develop with CORS disabled in safari to get around this.

CrafterSvK commented 3 years ago

@ryanbrwr Does your OPTIONS call to server return 200 OK?

ryanbrwr commented 3 years ago

I gave up a long time ago and used a different lib, appreciate it though.

MeyerMathieu commented 3 years ago

@ryanbrwr what lib did you used ? I am facing a similiar problem 😕

cohi-dev commented 3 years ago

@Elynad did you implement the app.before_request hook ?

MeyerMathieu commented 3 years ago

@cohi-dev Yes, I did

Here is a part of my code :

from flask import Flask
from flask_cors import CORS
from typing import List, Dict
import mysql.connector
import json

app = Flask(__name__)
CORS(app)

[...]

@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response

@app.route('/')
def hello() :
    return 'This is a test to check if the api is working.'

I also tried to replace CORS(app) with cors = CORS(app, resources={r"/*": {"origins": "*"}})

And I also tried to add @cross_origin() under each @app.route([...])

The thing is, everything is working fine in local (I am using dockers), but when these dockers are deployed on AWS EC2 instance, I get an XMLHttpRequest error 😕

CrafterSvK commented 3 years ago

Check network tab in browser and check preflight response paste it here.

MeyerMathieu commented 3 years ago

Screenshot 2021-07-20 at 18 58 34

I did not manage to copy it, but here you go

I just replaced "localhost" API address with "127.0.0.1", and I get the same result

shrhawk-entertainer commented 3 years ago

@Elynad what I did is

from flask import Response

@current_app.before_request
def basic_authentication():
    if request.method.lower() == 'options':
        return Response()
MeyerMathieu commented 3 years ago

@shrhawk-entertainer It seems to be a good answer, but where do you get request from ?

CrafterSvK commented 3 years ago

@shrhawk-entertainer It seems to be a good answer, but where do you get request from ?

You import it from flask module. Check documentation on how it works if you want to know how it works.

MeyerMathieu commented 3 years ago

Right. I added from flask import request.

Does not seems to work, I will make some tests this friday to keep you in touch

CrafterSvK commented 3 years ago

What do you mean by does not work. Do you have it registered in right blueprint. Have you tried breakpoint in that before request? Preflight request must return correct headers and respond with status 200.

MeyerMathieu commented 2 years ago

Preflight request did return status 200.

But the original request does not seems to work, and I get nothing in the "Response" tab when I click on the request.

Screenshot 2021-07-23 at 07 23 33

As I am testing a production deployment, I can't breakpoint, but I am writing in a log.txt file :

@app.before_request
def basic_authentication():
    file = open("log.txt", "w")
    file = open("log.txt", "a")
    file.write("In basic_authentication")
    if request.method.lower() == 'options':
        file.write("In basic_authentication ; returning Response()")
        return Response()

The log.txt file is not created, I suppose I am not even going in basic_authentication() function.

shuttle1987 commented 2 years ago

@Elynad I'd suggest that you use the logging functionality provided by flask to do this logging.

overbid commented 2 years ago

I think the best way to avoid this issue is add more rule for url like.

from werkzeug.routing import Rule

app = Flask(__name__, static_url_path='/static')
app.url_rule_class = lambda path, **options: Rule(
    app.static_url_path + path, **options
)
FLAGLORD commented 2 years ago

Did someone find some solution? It really sucks.....

echoboomer commented 2 years ago

Did someone find some solution? It really sucks.....

This worked brilliantly for me: https://github.com/corydolphin/flask-cors/issues/292#issuecomment-883929183

joaodlf commented 2 years ago

from flask import Response

@current_app.before_request def basic_authentication(): if request.method.lower() == 'options': return Response()

Wow. This works for me too. Effectively returning a 200 on OPTIONS requests (pre flight).

My app has no issues under 127.0.0.1 using this library, but as soon as I switched to localhost, I was hitting this same issue.

Would really like to understand why.

guruprakashIT commented 1 year ago

@joaodlf

You can use this way. because it's work for me

@app.before_request def before_request(): headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' } if request.method == 'OPTIONS' or request.method == 'options': return jsonify(headers), 200

it solve the cors issue

superdev87 commented 8 months ago

Did someone find another solution? I've tried all above, but not working in my side.

svrakata commented 8 months ago

For me the problem was in defining endpoints before setting CORS(app). No idea why.

mahendra-taiyo commented 3 months ago

This before request setup worked for me

@app.before_request
def before_request():
    headers = {'Access-Control-Allow-Origin': '*',
               'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
               'Access-Control-Allow-Headers': 'Content-Type'}
    if request.method.lower() == 'options':
        return jsonify(headers), 200
alamgiruk7 commented 5 days ago

This before request setup worked for me

@app.before_request
def before_request():
    headers = {'Access-Control-Allow-Origin': '*',
               'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
               'Access-Control-Allow-Headers': 'Content-Type'}
    if request.method.lower() == 'options':
        return jsonify(headers), 200

Thanks @mahendra-taiyo, This also worked for me. Moreover, In my case I figured out that I had used url_prefixes for all the apis which caused redirection and CORS doesn't allow preflight requests or redirects. So removing the url_prefixes while registering blueprints also worked for me But if you don't want to remove the prefixes then go with the above approach as mentioned by @mahendra-taiyo