我们在开发Flask应用程序时,通常通过运行Flask自带的Web服务器来开发测试,这个服务器提供了基本的但功能完备的WSGI服务器。但开发结束以后,在应用程序上线到生成环境时,有很多不得不考虑的事情,其中之一是我们是否应该要求客户端使用加密连接以增加安全性。
人们总是问我这个问题,特别是如何在HTTPS协议上部署Flask服务器。在本文中,我将介绍几种为Flask应用程序添加加密的方案,从一个非常简单的可以在五秒内实现,到一个强大的就像我的网站一样可以得到一个A +评级解决方案(我的网站的SSL分析数据)。
HTTPS是如何工作的?
HTTP的加密和安全功能是通过传输层安全性(TLS)协议实现的。实际上,TLS定义了一种使任何网络通信信道安全的标准方法。因为我不是一个安全专家,如果我试着给你一个TLS协议的详细描述,我认为我无法做到很好,所以我只想告诉你一些我们比较感兴趣的内容,要知道我们给Flask服务器设置安全和加密目的。
一般的思路是,当客户端与服务器建立连接并请求加密连接时,服务器将使用其SSL证书进行响应。证书此时作为服务器的标识,因为它包括服务器名和域名信息。为确保服务器提供的信息正确无误,证书是由证书颁发机构或CA进行加密签名的。如果客户端知道并信任CA,则可以确认证书签名确实来自该实体,并且客户端可以确定其连接的服务器是合法的。
客户端成功验证证书后,会创建用于与服务器通信的加密密钥。为确保将此密钥安全地发送到服务器,它使用服务器证书附带的公钥对其进行加密。服务器拥有与证书中的公钥一起使用的私钥,因此它是唯一能够解密包的一方。从服务器收到加密密钥时起,所有流量都使用只有客户端和服务器知道的密钥加密。
从上述总结中你可能会猜到,要实现TLS加密,我们需要两个项目:服务器证书,包括公钥并由CA签名,以及与证书中包含的公钥一起使用的私钥。
最简单的方法
Flask(更具体地说其实是Werkzeug),支持使用即时证书,这对于通过HTTPS快速提供应用程序非常有用,而且不会搞乱系统的证书。你只有需要做的就是将 ssl_context ='adhoc'
添加到程序的 app.run()
调用中。遗憾的是,Flask CLI无法使用此选项。举个例子,下面是官方文档中的“Hello,World” Flask应用程序,并添加了TLS加密:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():return "Hello World!"
if __name__ == "__main__":app.run(ssl_context='adhoc')
要在Flask中使用临时证书,你需要在虚拟环境中安装一个相关依赖项:
$ pip install pyopenssl
当你运行脚本时,就会注意到Flask指示它正在运行 https://
服务器:
$ python hello.py
* Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
很简单,对吧!这样有一个问题就是浏览器不喜欢这种类型的证书,因此浏览器会显示一个大而可怕的警告,你需要在访问应用程序之前先手动允许才可以访问。一旦允许浏览器连接,你就拥有了一个加密连接,就像从具有有效证书的服务器获得的连接一样,这使得这些临时证书便于开发中进行快速和验证测试,但不能用于任何实际生产环境中。