【问题标题】:can you add HTTPS functionality to a python flask web server?您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?
【发布时间】:2015-06-10 02:23:23
【问题描述】:

我正在尝试构建一个 Web 界面来在网络设备上模拟一个安静的界面,这个网络设备使用摘要式身份验证和 HTTPS。 我想出了如何将 Digest Authentication 集成到 Web 服务器中,但我似乎无法找到如何使用 FLASK 获取 https,如果你能告诉我如何请评论我需要用下面的代码做什么来实现它。

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()

【问题讨论】:

    标签: python rest https flask


    【解决方案1】:

    在真正的 Web 服务器上部署 Flask,而不是使用内置(开发)服务器。

    请参阅 Flask 文档的Deployment Options chapter。 Nginx 和 Apache 等服务器都可以为您的站点设置 HTTPS 服务器而不是 HTTP 服务器。

    列出的独立 WSGI 服务器通常部署在 Nginx 和 Apache 后面的代理转发配置中,前端服务器仍然为您处理 SSL 加密。

    【讨论】:

    • 如果您使用 mod_wsgi-express (pypi.python.org/pypi/mod_wsgi),它提供了一种使用 HTTPS 运行站点的简单方法,并且还具有在 Web 服务器级别处理 Digest 身份验证协议的内置功能。建议你在 mod_wsgi 邮件列表中询问它,因为 StackOverflow 不是一个讨论论坛,所以在这里不容易解释。
    • @Martijn Pieters,您能否解释一下为什么我们应该“在真正的 Web 服务器上部署 Flask,而不是使用内置(开发)服务器。”?谢谢
    • @Alexis.Rolland:内置服务器无法处理互联网的“真实世界”,它没有经过安全 POV 的强化,也没有针对性能进行调整。它的主要目的是在本地机器上引导开发,仅此而已。在生产环境中使用它需要您自担风险,在我看来这是一个相当大的风险。
    • 使用真正的网络服务器并不总是一种选择,我只想用 Flask 和 https 提供一些文件
    • @mazs:那么您将承担安全风险。安装 gunicorn 并使用它来为您的 Flask 服务是微不足道的,至少该服务器更加坚固。
    【解决方案2】:

    这在紧要关头也有效

    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)
    

    【讨论】:

    • SSLv3 存在 POODLE 漏洞。将其更改为 TSL
    • 点击此链接:flask.pocoo.org/snippets/111 在页面末尾的注释说明了如何更改为 TSL。
    • 你的意思是 TLS 不是 TSL?
    • 此用于创建 context 的代码已被较新的 python 弃用。试试这个:import ssl context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain('certificate.crt', 'private.key')
    • 我认为这里的 API 已经过时了。 My answer below 提供了一个适用于 Python 3.7.5 的版本。
    【解决方案3】:

    不要使用 openssl 或 pyopenssl 它现在在 python 中已经过时了

    参考下面的代码

    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)
    

    【讨论】:

    • 生成local.crtlocal.key见方法二:kracekumar.com/post/54437887454/ssl-for-flask-local-development
    • 很奇怪,它运行在http://127.0.0.1:5000/。这不应该在安全的http上运行吗?我仍然可以通过http://127.0.0.1:5000/获取
    • 我正在研究如何在 Dash 应用程序上实现 SSL,这个答案成功了,代码如下:context = ('local.crt','local.key') if __name__ == "__main__": app.run_server(host="192.168.200.100", port="8082", debug=True, ssl_context=context)
    • 我正在使用谷歌云运行。在这种情况下,对于生产,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中?
    • 这对我来说运行良好,但是当我使用 ssl_context=context 我的 index.html 不再加载链接的 .css 和 .js 本地文件。当我使用 ssl_context=None 运行应用程序时,html 会毫无问题地加载它们。这里有什么帮助吗?
    【解决方案4】:

    如果此网络服务器仅用于测试和演示目的。您可以使用 ngrok,它也是一个开源的,可以为您的 http 流量提供隧道。

    基本上,ngrok 创建一个公共 URL(http 和 https),然后将流量通过隧道传输到 Flask 进程正在运行的任何端口。

    https://ngrok.com/product

    设置只需几分钟。您首先必须下载该软件。然后运行命令
    ./ngrok http [你的python进程运行的端口号]

    然后它将在终端中打开一个窗口,为您提供 http 和 https 网址来访问您的网络应用程序。

    【讨论】:

    • 这真的很有效,没有太多安装/配置的麻烦。
    【解决方案5】:
    • 要在您的烧瓶应用程序中运行 HTTPS 功能或 SSL 身份验证,首先安装“pyOpenSSL”python 包
    pip install pyopenssl
    
    • 下一步是创建cert.pemkey.pem
    openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
    
    • 在您的烧瓶应用项目中复制生成的cert.pemkey.pem

    • app.run() 中添加ssl_context=('cert.pem', 'key.pem'),如下例所示。

    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"))
    

    【讨论】:

    • 我在第一步后遇到错误openssl' is not recognized as an internal or external command
    • 你安装了pyopenssl吗?
    • 是的,我已经安装了....稍后当我尝试第 2 步时 to create 'cert.pem' and 'key.pem' 它向我显示了错误
    • 如果你在windows中,你必须将它添加到路径中。
    • 您也必须下载它。来自网站,而不是来自 pip。
    【解决方案6】:

    对于快速的 n' 脏自签​​名证书,您还可以使用 flask run --cert adhoc 或设置 FLASK_RUN_CERT 环境变量。

    $ 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
    

    adhoc 选项没有很好的文档记录(有充分的理由,永远不要在生产中这样做),但在 cli.py source code 中提到了它。

    Miguel GrinbergRunning Your Flask Application Over HTTPS 对此进行了详尽的解释。

    【讨论】:

    • 我正在使用谷歌云运行。在这种情况下,对于生产,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中?
    【解决方案7】:

    The top-scoring answer 的想法是正确的,但 API 似乎已经发展,以至于它不再像 2015 年首次编写时那样工作。

    代替这个:

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

    我在 Python 3.7.5 中使用过这个:

    import ssl
    context = ssl.SSLContext()
    context.load_cert_chain('fullchain.pem', 'privkey.pem')
    

    然后在 Flask.run 调用中提供 SSL 上下文,正如它所说:

    app.run(…, ssl_context=context)
    
    

    (我的server.crt 文件称为fullchain.pem,我的server.key 称为privkey.pem。这些文件是由我的 LetsEncrypt Certbot 提供给我的。)

    【讨论】:

    • SSL POODLE 漏洞怎么样?
    • 我正在使用谷歌云运行。在这种情况下,我只需要从 CA 购买证书,然后他们按照您的回答将其放入我的应用程序中?
    • 嘿,马克,您究竟是如何生成这些 crt pem 和密钥的?
    • 呸忘了我看到了我们刚刚重命名的 server.crt 和密钥我在 wsl 上使用了 openssl 来生成它们
    【解决方案8】:

    超级简单:

    app.py

    from flask import Flask
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        return "Hello World!"
    

    运行:

    $ openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
    $ flask run --cert=cert.pem --key=key.pem
    

    【讨论】:

      猜你喜欢
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多