Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doubt] Enable CORS with connexion #357

Closed
ernanirst opened this issue Dec 2, 2016 · 9 comments
Closed

[Doubt] Enable CORS with connexion #357

ernanirst opened this issue Dec 2, 2016 · 9 comments
Assignees
Labels

Comments

@ernanirst
Copy link

Description

I have a static file with some jQuery that access an API built with connexion. Unfortunatelly, the browser requires CORS to be enable in order to access the API. I couldn't find a way of adding fields to the headers response nor a module or option to do that, so I'm not sure on what to do about.

Additional info:

Another possible workaround would be if I could just serve this static code with Connexion, I found lots of solutions for Flask but nothing that worked with Connexion

Output of the commands:

  • python --version
    Python 3.4.3
@Jkovarik
Copy link

Jkovarik commented Dec 2, 2016

Hi @ernanirst - I believe you can access the underlying flask 'app' object and enable CORS the same way you'd do it with a flask service like so:

import connexion
from connexion.resolver import RestyResolver
from flask_cors import CORS

app = connexion.App(__name__)
CORS(app.app)
app.add_api('api.yaml', resolver=RestyResolver('seaiceservices.api'))

@hjacobs
Copy link
Contributor

hjacobs commented Dec 2, 2016

@ernanirst see #50 for answers/discussion, using flask-cors looks good enough for me.

@hjacobs hjacobs closed this as completed Dec 2, 2016
@hjacobs
Copy link
Contributor

hjacobs commented Dec 2, 2016

Re-opening, as we should add a section regarding CORS on http://connexion.readthedocs.io/en/latest/cookbook.html

@hjacobs
Copy link
Contributor

hjacobs commented Dec 2, 2016

See my PR #358.

@ernanirst
Copy link
Author

Thanks a lot, I've tried something very similar which did not work, but this worked fine. I suggest that you add this to the docs because I looked there and found nothing. Thanks again.

@zimmicz
Copy link

zimmicz commented Oct 5, 2018

I'm trying to use flask cors with connexion

#!/usr/bin/env python3

import config
import connexion
import logging
import logging.handlers
from connexion.resolver import RestyResolver
from flask.logging import default_handler
from flask_jwt_extended import JWTManager
from flask_cors import CORS

def create_app():
    app = connexion.FlaskApp(__name__, specification_dir='swagger/')
    app.add_api('mapmybook.yaml', validate_responses=True, strict_validation=True, resolver=RestyResolver('api'))

    app.app.config.from_object(config.DevelopmentConfig)
    app.app.logger.addHandler(create_file_handler())

    jwt = JWTManager(app.app)
    return app.app # return <Flask> object

def create_file_handler():
    ...
    return rfh

if __name__ == '__main__':
    app = create_app()
    CORS(app.app)
    app.run(port=5000)

Yet when I send a request

curl 'http://127.0.0.1:5000/v1.0/login' -X OPTIONS -H 'Pragma: no-cache' -H 'Access-Control-Request-Method: POST' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 OPR/56.0.3051.36' -H 'Accept: */*' -H 'Cache-Control: no-cache' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Access-Control-Request-Headers: content-type' --compressed

I get

Failed to load http://127.0.0.1:5000/v1.0/login: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access```

What else do I have to set to make this work with application/json content type?

@Morabaraba
Copy link

Just a stab in the dark. But add the resources argument, for example:

...
CORS_RESOURCES = {r"/v1/*": {"origins": "*"}, r"/v1.0/*": {"origins": "*"}, r"/v1.1/*": {"origins": "*"}}
CORS(app.app, resources=CORS_RESOURCES)
...

@zimmicz
Copy link

zimmicz commented Oct 5, 2018

Seems @cross_origin decorator solves the problem, but CORS(app) alone is not working.

@dirkschneemann
Copy link

dirkschneemann commented Nov 23, 2018

Just for reference, for simple use cases you can simply add the required headers yourself to all responses. There is two ways to achieve this.

Using a custom middleware:

class CorsHeaderMiddleware(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        def custom_start_response(status, headers, exc_info=None):
            # append whatever headers you need here
            headers.append(('Access-Control-Allow-Origin', '*'))
            headers.append(
                ('Access-Control-Allow-Headers', 'X-Requested-With')
            )
            headers.append(('Access-Control-Allow-Methods', 'OPTIONS'))
            return start_response(status, headers, exc_info)

        return self.app(environ, custom_start_response)

connexion_app = connexion.FlaskApp(__name__, specification_dir='.')
connexion_app.add_api('specification.yml')
connexion_app.app.wsgi_app = CorsHeaderMiddleware(connexion_app.app.wsgi_app)

Using Flask's after_request hook:

def set_cors_headers_on_response(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Headers'] = 'X-Requested-With'
    response.headers['Access-Control-Allow-Methods'] = 'OPTIONS'
    return response

connexion_app = connexion.FlaskApp(__name__, specification_dir='.')
connexion_app.add_api('api_specification.yml')
connexion_app.app.after_request(set_cors_headers_on_response)

While the Flask hook approach is a bit shorter, the WSGI middleware will keep working even when switching to a different backend like tornado or gevent later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants