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

Support CORS #131

Closed
KangOl opened this issue Nov 3, 2011 · 16 comments · Fixed by #1699
Closed

Support CORS #131

KangOl opened this issue Nov 3, 2011 · 16 comments · Fixed by #1699
Milestone

Comments

@KangOl
Copy link

KangOl commented Nov 3, 2011

It would be nice to support CORS [1][2]

even static files need to support it

[1] http://www.w3.org/TR/cors/
[2] http://enable-cors.org/

@DasIch
Copy link
Contributor

DasIch commented Jun 20, 2013

Werkzeug already supports CORS in that you can set the headers on the responses you return in your WSGI application. I'm not sure what else can or should be done within Werkzeug to "support CORS", can you elaborate on that?

@quasipedia
Copy link

I'm not the OP, but since CORS is pretty much a boilerplate header injection, it might perhaps be a good idea to have it as a setting/parameter. Something along the lines of this snippet, although here-notably there is no OPTIONS, so the preflight will be problematic...

    if 'cors' in config and config['cors'] is True:
        response.headers.add('Access-Control-Allow-Origin', '*')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,PUT,POST,DELETE,PATCH')
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type, Authorization')

...you know the python mantra: "batteries included"... ;)

@posativ
Copy link
Contributor

posativ commented Feb 19, 2014

But CORS is more than allowing *, especially when you use cookies and stuff. Personally, I use a 20 LoC WSGI middleware to add CORS headers and answer preflight request. It's not that hard.

@quasipedia
Copy link

@posativ - Care to share on a gist maybe? :)

@posativ
Copy link
Contributor

posativ commented Feb 20, 2014

In a very limited form:

from werkzeug.datastructures import Headers

class CORSMiddleware(object):
    """Add Cross-origin resource sharing headers to every request."""

    def __init__(self, app, origin):
        self.app = app
        self.origin = origin

    def __call__(self, environ, start_response):

        def add_cors_headers(status, headers, exc_info=None):
            headers = Headers(headers)
            headers.add("Access-Control-Allow-Origin", self.origin)
            headers.add("Access-Control-Allow-Headers", "Origin, ...")
            headers.add("Access-Control-Allow-Credentials", "true")
            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, etc")
            headers.add("Access-Control-Expose-Headers", "...")
            return start_response(status, headers.to_list(), exc_info)

        if environ.get("REQUEST_METHOD") == "OPTIONS":
            add_cors_headers("200 Ok", [("Content-Type", "text/plain")])
            return [b'200 Ok']

        return self.app(environ, add_cors_headers)

# usage
app = CORSMiddleware(make_app(...), "http://example.org/")

You may extend this class to include custom headers, credentials, wild-cards.

@quasipedia
Copy link

@posativ - Thank you for this, I'll try it early next week when I'll resume work on that project. :)

@lambdaq
Copy link

lambdaq commented Apr 19, 2016

Need to bump this up.

Relative question http://stackoverflow.com/questions/19382431/set-header-on-werkzeug-exception

Related line: https://github.com/pallets/werkzeug/blob/master/werkzeug/debug/__init__.py#L297

the start_response('500 INTERNAL SERVER ERROR', makes it hard to add CORS header like Access-Control-Allow-Origin: *. But curiously we already have X-XSS-Protection: 0 there.

I have Flask-CORS enabled, been debugging a tricky remote ajax API call in Chrome, when Flask has an exception, I can not see the debug content because of CORS. Can we add this header in debug model?

@untitaker
Copy link
Contributor

untitaker commented Apr 19, 2016

Why would you want to set a CORS header on the debugger? And why can't you do that with a wrapping middleware?

@untitaker
Copy link
Contributor

Also I want to close this since I don't think we need to add every middleware to werkzeug.

@lambdaq
Copy link

lambdaq commented Apr 20, 2016

@unititaker

Why would you want to set a CORS header on the debugger?

Because it's a tricky scenario invoked by cross-domain AJAX request, in can only debug it in Chrome DevTool after series of javascript event triggering, if no CORS header, the Chrome DevTool does not display any content at all. I cant see nothing. I can only stare at a blank page with 500 server error.

And why can't you do that with a wrapping middleware?

because wrapped middleware works with only NORMAL (proper returned Flask application ) pages, but does not work at all when Werkzeug exception debugger happens.

Here's the "wrapping middleware" you referring to, corydolphin/flask-cors#67 you can see we cant do much about it unless lower level Werkzeug stuff was tweaked.

I presume @untitaker did not take a look at the source code I linked? Here's a screenshot:

qq20160420-3

@RonnyPfannschmidt
Copy link
Contributor

@lambdaq now you are being mean to @untitaker

any middleware that does wrap around a debug wrapped application can change the start_response behaviour - even for the debugger - so the code you pasted and linked seems completely irrelevant,
since a cors middle-ware wrapping around could just change it

perhaps im missing your exact problem, due to different perspective/understanding please outline the exact use-case that seems broken/impossible

@untitaker
Copy link
Contributor

The situation is made a bit tricky because the debugger middleware is applied when calling app.run. Still you can work around this by applying both your CORS and the debugger middleware manually. IMO this is fine for such an edgecase, but if you have concrete proposals for changing the debugger middleware in a way that doesn't compromise security, please do suggest them. I don't know of any easy changes though.

Also I am well aware of the code in Werkzeug. I guess that's why I'm maintaining it?

@lambdaq
Copy link

lambdaq commented Apr 20, 2016

sorry, I apologize for my language, Werkzeug is awesome project.

I guess I just have to monkey edit these start_response() lines and add CORS header bruteforce for my dev environment, it's more convenient than a hairy middleware.

@untitaker
Copy link
Contributor

Also you might consider adding extra JS code instead that redirects to the debugger if a 500 response comes back.

@lambdaq
Copy link

lambdaq commented Apr 20, 2016

@untitaker JS code can do nothing, if there's 500 error, you can only tell its http status code is 500, the traceback from the debugger page is what I am after.

also the js code is hairy compiled reactjs with tons of stuff, developed by another team, it takes 300s+ to npm run dev. Not easy to tweak or add few debug lines.

@pgjones
Copy link
Member

pgjones commented Jan 11, 2020

I think #1699 resolves this. Whilst Werkzeug could do more than is in #1699, I think it should just provide accessor methods (like for cache control) and allow tools built on it (e.g. Flask-CORS or Quart-CORS) to do CORS logic.

@davidism davidism added this to the 1.0.0 milestone Jan 12, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants