您可以将 HTTPS 功能添加到 python flask 网络服务器吗?

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

我正在尝试构建一个 Web 界面来模拟网络设备上的 restful 界面,该网络设备使用摘要身份验证和 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()

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

请参阅 Flask 文档的 Deployment Options chapter。 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)

不要使用 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)

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

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

https://ngrok.com/product

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

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

  • 为了运行 Flask 应用程序中的 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 在你的 flask 应用程序项目中

  • 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' dirty 自签名证书,您还可以使用 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 Grinberg at Running Your Flask Application Over 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')

我用过这个,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 提供给我。)

超级简单:

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

截图: