您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?

Posted

技术标签:

【中文标题】您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?【英文标题】:can you add HTTPS functionality to a python flask web server? 【发布时间】: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()

【问题讨论】:

【参考方案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 邮件列表中询问它,因为 *** 不是一个讨论论坛,所以在这里不容易解释。 @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

【讨论】:

以上是关于您可以将 HTTPS 功能添加到 python 烧瓶 Web 服务器吗?的主要内容,如果未能解决你的问题,请参考以下文章

逻辑烧脑:python 区块链的简易实现

涂鸦蓝牙SDK开发系列教程——4.烧录授权

将python脚本添加到c ++项目

您可以将现有表添加到 MySQL Workbench 中的现有模型吗?

IAR 可以将程序烧写到特定的Flash地址吗

从零开始DevEcoTool编译烧录OpenHarmony3.1