can you add HTTPS functionality to a python flask web server?

151,128

Solution 1

this also works in a pinch

from flask import Flask, jsonify


from OpenSSL import SSL
context = SSL.Context(SSL.PROTOCOL_TLSv1_2)
context.use_privatekey_file('server.key')
context.use_certificate_file('server.crt')   


app = Flask(__name__)


@app.route('/')
def index():
    return 'Flask is running!'


@app.route('/data')
def names():
    data = {"names": ["John", "Jacob", "Julie", "Jennifer"]}
    return jsonify(data)


#if __name__ == '__main__':
#    app.run()
if __name__ == '__main__':  
     app.run(host='127.0.0.1', debug=True, ssl_context=context)

Solution 2

Don't use openssl or pyopenssl its now become obselete in python

Refer the Code below

from flask import Flask, jsonify
import os

ASSETS_DIR = os.path.dirname(os.path.abspath(__file__))
app = Flask(__name__)


@app.route('/')
def index():
    return 'Flask is running!'


@app.route('/data')
def names():
    data = {"names": ["John", "Jacob", "Julie", "Jennifer"]}
    return jsonify(data)


if __name__ == '__main__':
    context = ('local.crt', 'local.key')#certificate and key files
    app.run(debug=True, ssl_context=context)

Solution 3

  • To run HTTPS functionality or SSL authentication in your flask application, first install "pyOpenSSL" python package
pip install pyopenssl
  • Next step is to create cert.pem and key.pem
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
  • Copy generated cert.pem and key.pem in your flask application project

  • Add ssl_context=('cert.pem', 'key.pem') in app.run(), like in the example below.

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/")
def index():

    return "Flask is running!"


@app.route("/data")
def names():

    data = {"names": ["John", "Jacob", "Julie", "Jennifer"]}

    return jsonify(data)


if __name__ == "__main__":

    app.run(ssl_context=("cert.pem", "key.pem"))

Solution 4

Deploy Flask on a real web server, rather than with the built-in (development) server.

See the Deployment Options chapter of the Flask documentation. Servers like Nginx and Apache both can handle setting up HTTPS servers rather than HTTP servers for your site.

The standalone WSGI servers listed would typically be deployed behind Nginx and Apache in a proxy-forwarding configuration, where the front-end server handles the SSL encryption for you still.

Solution 5

For a quick n' dirty self-signed cert, you can also use flask run --cert adhoc or set the FLASK_RUN_CERT env var.

$ export FLASK_APP="app.py"
$ export FLASK_ENV=development
$ export FLASK_RUN_CERT=adhoc

$ flask run
 * Serving Flask app "app.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 329-665-000

The adhoc option isn't well documented (for good reason, never do this in production), but it's mentioned in the cli.py source code.

There's a thorough explanation of this by Miguel Grinberg at Running Your Flask Application Over HTTPS.

Share:
151,128
robm
Author by

robm

Updated on October 13, 2021

Comments

  • robm
    robm over 2 years

    I am trying to build a web interface to Mock up a restful interface on networking device this networking device uses Digest Authentication and HTTPS. I figured out how to integrate Digest Authentication into the web server but I cannot seem to find out how to get https using FLASK if you can show me how please comment on what i would need to do with the code below to make that happen.

    from flask import Flask, jsonify
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def index():
        return 'Flask is running!'
    
    
    @app.route('/data')
    def names():
        data = {"names": ["John", "Jacob", "Julie", "Jennifer"]}
        return jsonify(data)
    
    
    if __name__ == '__main__':
        app.run()
    
  • Graham Dumpleton
    Graham Dumpleton about 9 years
    If you use mod_wsgi-express (pypi.python.org/pypi/mod_wsgi) it provides an easy way of running up a site with HTTPS, plus has builtin capabilities for handling Digest authentication protocol at the web server level as well. Suggest you ask about it on the mod_wsgi mailing list as StackOverflow is not a discussion forum and so not as easily explained here.
  • OWADVL
    OWADVL about 8 years
    SSLv3 has POODLE vulnerability. Change it to TSL
  • Pierre Cordier
    Pierre Cordier almost 8 years
    Following this link : flask.pocoo.org/snippets/111 At the end of the page a comment explains how to change to TSL.
  • Alexis.Rolland
    Alexis.Rolland almost 7 years
    @Martijn Pieters, Could you please explain why we should "Deploy Flask on a real web server, rather than with the built-in (development) server."? Thanks
  • Martijn Pieters
    Martijn Pieters almost 7 years
    @Alexis.Rolland: the built-in server is not equipped to deal with the 'real world' of the internet, it has not been battlehardened from a security POV nor has it been tuned for performance. It's primary purpose is to bootstrap development on a local machine, nothing more. Using it in a production environment is at your own risk, which in my opinion is a rather large risk.
  • andyandy
    andyandy almost 7 years
    To generate local.crt and local.key see Method 2 of: kracekumar.com/post/54437887454/ssl-for-flask-local-developm‌​ent
  • prayagupa
    prayagupa over 6 years
    weird, it runs at http://127.0.0.1:5000/. is not this supposed to run on secure http. I Still can GET at http://127.0.0.1:5000/
  • damaniel
    damaniel about 6 years
    You mean TLS not TSL?
  • magor
    magor over 5 years
    using a real webserver is not always an option, i just want to serve some files with Flask and https
  • Martijn Pieters
    Martijn Pieters over 5 years
    @mazs: then you take the security risk. And it's trivial to install gunicorn and use that to serve your Flask, that server at least is much more battle hardened.
  • KcH
    KcH about 4 years
    i got an error after first step as openssl' is not recognized as an internal or external command
  • vaishali KUNJIR
    vaishali KUNJIR about 4 years
    Did you installed pyopenssl?
  • KcH
    KcH about 4 years
    yes i have installed ....later when I am trying step 2 to create 'cert.pem' and 'key.pem' it shown me the error
  • KetZoomer
    KetZoomer almost 4 years
    You have to add it to path if you are in windows.
  • KetZoomer
    KetZoomer almost 4 years
    You also have to download it. From the website, not from pip.
  • nimi
    nimi almost 4 years
    This code for creating the context is deprecated for newer python. Try this: import ssl context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain('certificate.crt', 'private.key')
  • NicolasZ
    NicolasZ over 3 years
    I was looking on how to implement SSL on a Dash app and this answer did the trick, here is the code: context = ('local.crt','local.key') if __name__ == "__main__": app.run_server(host="192.168.200.100", port="8082", debug=True, ssl_context=context)
  • Mark Dominus
    Mark Dominus over 3 years
    I think the API here is obsolete. My answer below gives a version of this that worked with Python 3.7.5.
  • tremendows
    tremendows about 3 years
    what about SSL POODLE vulnerability?
  • Amit Tomar
    Amit Tomar about 3 years
    This really worked without much hassle of installing/configuring stuff.
  • Gabriel Schubert
    Gabriel Schubert about 3 years
    I'm using google cloud run. In this case I only need to buy a certificate from a CA and them put it into my app following your answer?
  • Gabriel Schubert
    Gabriel Schubert about 3 years
    I'm using google cloud run. In this case, for production, I only need to buy a certificate from a CA and them put it into my app following your answer?
  • Gabriel Schubert
    Gabriel Schubert about 3 years
    I'm using google cloud run. In this case, for production, I only need to buy a certificate from a CA and them put it into my app following your answer?
  • RobM
    RobM almost 3 years
    Hey Mark how exactly did you generate those crt pem and key?
  • RobM
    RobM almost 3 years
    bah forget that I see the server.crt and key we just renamed I used openssl on wsl to generate them
  • Matheus Torquato
    Matheus Torquato almost 3 years
    This is running fine for me, but when I use ssl_context=context my index.html does not load the linked .css and .js local files anymore. When I run the app with ssl_context=None the html loads them with no problem. Any help here?
  • Jim JR Harris
    Jim JR Harris over 2 years
    @MatheusTorquato This is because, apparently, the default values for ssl_context, or ssl_context = context loads a set of restrictions that, essentially, lock down the site extremely tightly. At the site discussing Talisman as a way to secure Flask, (betterprogramming.pub/…), they say that for the usual site using SSL, this may not be necessary. Of course, that depends on your site and YMMV.