Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add response headers to flask web app

I have a flask web app which uses render_template as follows.I need to add a Content-Security-Policy as additional http response headerin the response. I tried following ways but both fail and give me 500.

1.

from flask import \
Flask, \
render_template
app = Flask(__name__,template_folder='tmpl')
@app.route('/')
def index():
    resp =make_response(render_template('index.html'))
    resp.headers['Content-Security-Policy']='default-src \'self\'' 
    return resp

if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)

2.

@app.route('/')
def index():
    resp =render_template('index.html')
    resp.headers.add('Content-Security-Policy','default-src \'self\'') 
    return resp

if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)   

What can be wrong here?

On the terminal i see following when I access the web app as localhost:3001

127.0.0.1 - - [06/Apr/2015 01:45:01] "GET / HTTP/1.1" 500 -

like image 572
WillMcavoy Avatar asked Apr 06 '15 01:04

WillMcavoy


People also ask

How do you create a response object in Flask?

Flask provides a method called make_response() that we can use to send custom headers, as well as change the property (like status_code , mimetype , etc.) in response. We can import make_response from the flask . make_response() accepts a string as a parameter, then creates and returns a response object.


2 Answers

The prettiest way to handle this, assuming that you want to same headers attached to all of your responses is with flasks builtin decorator:

@app.after_request

So in this case just add this function to your routes module:

@app.after_request
def add_security_headers(resp):
    resp.headers['Content-Security-Policy']='default-src \'self\''
    return resp

With this in place your functions just return the render_template(...) value as before and flask automatically wraps it in a response which is passed to the after_request function before being returned to the client.

like image 38
Sam Redway Avatar answered Oct 03 '22 16:10

Sam Redway


render_template returns a string, not a response. A string returned from a view is automatically wrapped in a response by Flask, which is why you may be confused. Construct the response with the rendered template.

from flask import make_response
r = make_response(render_template('index.html'))
r.headers.set('Content-Security-Policy', "default-src 'self'")
return r
like image 142
davidism Avatar answered Oct 03 '22 16:10

davidism