你能给 python flask web 服务器添加 HTTPS 功能吗?

我试图建立一个网络界面,以模拟一个静止的网络设备接口,这个网络设备使用摘要认证和 HTTPS。 我想出了如何将摘要认证集成到 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()
183197 次浏览

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

请参阅 Flask 文档的 < em > 部署选项 章节。像 Nginx 和 Apache 这样的服务器都可以为站点设置 HTTPS 服务器,而不是 HTTP 服务器。

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

这在紧要关头也有效

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)

不要使用 开放式或开放式,它现在已经过时了

请参阅以下守则

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)

如果这个网站服务器只是为了测试和演示的目的。您可以使用 ngrok,它也是一个开放源码,可以通道您的 http 流量。

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

Https://ngrok.com/product

只需要几分钟就可以设置好。首先你必须下载软件,然后运行命令
./ngrok http [运行 Python 进程的端口号]

然后它会在终端中打开一个窗口,提供一个 http 和 https 地址来访问你的 web 应用程序。

  • 要在烧瓶应用程序中运行 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"))

对于一个快速的 n’脏自签名证书,您也可以使用 flask run --cert adhoc或设置 FLASK_RUN_CERT env 变量。

$ 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选项没有详细的文档说明(出于好的理由,在生产中永远不要这样做) ,但是在 Py 源代码中提到了它。

通过 HTTPS 运行烧瓶应用程序米格尔 · 格林伯格对此有一个详尽的解释。

得分最高的答案 的想法是正确的,但 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')

我在 Python3.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 提供给我的。)

超级简单:

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

可以使用 Mkcert生成浏览器信任的证书。

mkcert example.com "*.example.com" example.test localhost 127.0.0.1 ::1

浏览器将信任下列所有域和 IP

- "example.com"
- "*.example.com"
- "example.test"
- "localhost"
- "127.0.0.1"
- "::1"

Python 代码:

from flask import Flask, jsonify


app = Flask(__name__)




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


return "Welcome to the Python Flask's Index!"






if __name__ == "__main__":
app.run(port=443, ssl_context=("localhost+3.pem", "localhost+3-key.pem"))

截图: screenshot