【发布时间】:2020-01-15 13:40:12
【问题描述】:
我正在使用 python socketio 进行通信,它适用于 http。升级它以使用 SSL 时出现问题。
我制作了自签名根证书 (CA),并颁发了 server.cert 和 server.key。我告诉计算机信任 CA。之后,我在 flask-socketio 服务器端添加了 server.cert 和 server.key。代码如下所示:
from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_socketio import Namespace
app = Flask(__name__, template_folder="templates")
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
# Create a URL route in our application for "/"
@app.route('/')
def home():
"""
This function loads the homepage
"""
return render_template('index.html')
class MyCustomNamespace(Namespace):
def on_connect(self):
print("Client just connected")
def on_disconnect(self):
print("Client just left")
def on_messages(self, data):
print(f"\nReceived data from client: \n {data}\n")
return data
socketio.on_namespace(MyCustomNamespace('/channel_A'))
if __name__ == "__main__":
socketio.run(app, host="192.168.0.28", port=2000, certfile="server.crt", keyfile="server.key", server_side=True, debug=True)
#socketio.run(app, host="192.168.0.28", port=2000, debug=True)
客户端连接的代码很简单:
import socketio
sio = socketio.Client()
def message_received(data):
print(f"Message {data} received")
@sio.on('connect', namespace="/channel_A")
def on_connect():
print("Connect...")
@sio.on('disconnect', namespace="/channel_A")
def on_disconnect():
print(f"Disconnected from server")
if __name__ == '__main__':
sio.connect('https://192.168.0.28:2000', namespaces="/channel_A")
emit_times = 0
is_emit = True
data = '{"data": "foobar"}'
while is_emit:
sio.emit("messages", data, namespace="/channel_A", callback=message_received)
emit_times += 1
if emit_times > 1:
is_emit = False
sio.disconnect()
我在客户端使用 python-socketio (https://python-socketio.readthedocs.io/en/latest/client.html#disconnecting-from-the-server)。
服务器启动后,网站运行良好,连接安全。命令行如下所示:
* Restarting with stat
* Debugger is active!
* Debugger PIN: 142-782-563
(3484) wsgi starting up on https://192.168.0.28:2000
当 SocketIO 客户端尝试与服务器连接时,连接被拒绝,在服务器端,错误最终抛出如下:
ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:2488)
我想我可能错过了什么。有任何想法吗?提前致谢!
【问题讨论】:
-
“我告诉计算机信任 CA”到底是什么意思?您可能将浏览器配置为信任它,这与使用 Python 客户端是分开的。您可以通过 REQUESTS_CA_BUNDLE 环境变量为 python 请求提供受信任的 CA,但 websocket 请求目前没有类似的选项。
-
您好,感谢您的回复。我创建了一个自签名根 ssl 证书并将其添加到我的 Mac 的 KeyChains 中。这就是我告诉计算机信任 CA 的方式。
-
您的代码使用的是自己的信任库,而不是操作系统...
-
您好帕特里克,感谢您的回复!请您再解释一下好吗?
-
例如,Firefox 默认不使用操作系统信任库,而是使用它自己的信任库。有关详细信息,请参阅support.mozilla.org/en-US/kb/…。对于您的 Python 代码也是如此,它可能使用自己的信任库,而不是操作系统。所以你必须在适当的地方添加你的特定证书。
标签: python ssl flask-socketio python-socketio