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

Why flask_cors didn't return response directly (before Decorator @before_request) when get a OPTIONS request? #196

Closed gasxia closed 7 years ago

gasxia commented 7 years ago
def create_app(config_name):
    app = Flask(__name__)
    logging.getLogger('flask_cors').level = logging.DEBUG
    CORS(app)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    db.init_app(app)

    # 注册api蓝本
    from .api import api as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api')
    # todo: 处理路由与错误页面

    return app

Error In before_request api/auth.py

from flask import g, request
from flask.ext.httpauth import HTTPBasicAuth
from .errors import forbidden
from flask_cors import cross_origin
from . import api
from ..models import User

auth = HTTPBasicAuth()

@auth.verify_password
def verify_password(username, password):
    user = User.query.filter_by(username = username).first()
    if not user:
        return False
    g.current_user = user
    return user.verify_password(password)

@api.before_request
# @cross_origin()
@auth.login_required
def before_request():
    # pass
    if not g.current_user: # request.method != 'OPTIONS' and not g.current_user:
        return forbidden('Unconfirmed account')

When I send a auth fetch. I'm getting the error.

127.0.0.1 - - [10/Mar/2017 12:35:25] "OPTIONS /api/posts/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1610, in full_dispatch_request
    rv = self.preprocess_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1831, in preprocess_request
    rv = func()
  File "/usr/local/lib/python2.7/site-packages/flask_httpauth.py", line 93, in decorated
    return f(*args, **kwargs)
  File "/Users/jinrunsen/Dev/Projects/learn-flask/user-api/app/api/auth.py", line 24, in before_request
    if not g.current_user:# request.method != 'OPTIONS' and not g.current_user:
  File "/usr/local/lib/python2.7/site-packages/werkzeug/local.py", line 343, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: '_AppCtxGlobals' object has no attribute 'current_user'

Why flask_cors didn't return response directly (before Decorator @before_request) when get a OPTIONS request?

gasxia commented 7 years ago

I use the below code can make this request run correct.
But I still not clear why flask_cors can't do it automatic for me.

@api.before_request
# @cross_origin()
@auth.login_required
def before_request():
    # pass
    if request.method != 'OPTIONS' and not g.current_user:
        return forbidden('Unconfirmed account')
corydolphin commented 7 years ago

Hmm, sorry for the trouble here @gasxia I think this may be related to the intercept_exceptions option misbehaving.

Can you try to disable 'intercept_exceptions' by setting intercept_exceptions=false and let me know if that fixes things?

gasxia commented 7 years ago

Hi @corydolphin: Thanks for your help and reply. I add the setting in CORS(app).

def create_app(config_name):
    app = Flask(__name__)
    logging.getLogger('flask_cors').level = logging.DEBUG
    CORS(app, intercept_exceptions=False)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    db.init_app(app)
    refresh_kfz_cookies(kfz_session)
    # 注册api蓝本
    from .api import api as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api')
    # todo: 处理路由与错误页面

    return app

Then it can pass OPTIONS method, but it lead to another problem.

127.0.0.1 - - [14/Apr/2017 12:38:52] "OPTIONS /api/token/ HTTP/1.1" 200 -
127.0.0.1 - - [14/Apr/2017 12:38:52] "GET /api/token/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1610, in full_dispatch_request
    rv = self.preprocess_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1831, in preprocess_request
    rv = func()
  File "/usr/local/lib/python2.7/site-packages/flask_cors/decorator.py", line 128, in wrapped_function
    resp = make_response(f(*args, **kwargs))
  File "/usr/local/lib/python2.7/site-packages/flask/helpers.py", line 191, in make_response
    return current_app.make_response(args)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1725, in make_response
    raise ValueError('View function did not return a response')
ValueError: View function did not return a response
corydolphin commented 7 years ago

Looks like an error in your view logic. Please post a minimal working example -- I don't believe flask-cors is the issue here.

homekeeper89 commented 5 years ago

Hello corydolphin! i had a same issue about

Looks like an error in your view logic. Please post a minimal working example -- I don't believe flask-cors is the issue here.

Hello! corydolphin i had a same issue about that. I want to use cross_origin decorator with @before_request, but the return is ' ValueError: View function did not return a response'.

https://gist.github.com/homekeeper89/f1b9fa82ce1f3f6b8459c6af022a122f

This is my code and i just want to check authority, so these function didn't return anything. I think that this function must return kind of WSGI(-> the view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a LocalProxy.), but i don't know how to return Can you give some advice for me? Thanks for reading.