前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。
我們的Server端套用了FastAPI框架, 以這樣的寫法載入SSL憑證:
uvicorn.run(
app,
host='0.0.0.0',
port=int(args.port),
ssl_keyfile=args.ssl_keyfile,
ssl_certfile=args.ssl_certfile,
)
您可能會透過「【Prompt Engineering 提示工程】Ep.1 什麼是Prompt Engineering?」的技巧去詢問AI問題, 但直觀的會得到這樣的答案:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.load_verify_locations('/path/to/your/certificate.pem')
async with websockets.connect(
'wss://your.websocket.server',
ssl=ssl_context,
) as websocket:
...
這很正確沒錯, 確實在生產環境使用這種標準方式非常安全, 但麻煩的是還需要這個憑證檔(.pem), 有時候我們在其他臺主機想要快速連線, 又不希望帶上憑證檔時該怎麼辦呢?
這時候聰明的我們可能會這樣問ChatGPT, 請問「如果我不想用pem連線, 而是希望用insecure」, 那麼它可能回答我們這樣的問題:
async with websockets.connect(
'ws://your.websocket.server', # 使用 ws://,而不是 wss://
ssl=False, # 关闭 SSL/TLS 连接的证书验证
) as websocket:
...
這看起來很合理對吧! 但別忘了開頭有提到我們的伺服器是以SSL方式架設, 這跑下去肯定會 💣 , 果不其然發生了這樣的錯誤…
connect() received a ssl argument for a ws:// URI, use a wss:// URI to enable TLS
不死心的我們加了點變化, 強制在URL用wss連線, 結果…
did not receive a valid HTTP response
!!! 難道沒招了嗎? 不不不, 既然我們的https都有insecure的連線方式了, 難道websocket沒有嗎? 這不可能, 沒關係, 我知道您現在也非常納悶為什麼 ssl=False沒有用, 就讓我們來分享一下正確的使用方式吧!
🌟 本章精華重點
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
async with websockets.connect(
'wss://your.websocket.server',
ssl=ssl_context,
) as websocket:
...
我們學會與AI合作固然是好事, 但它給的答案並不能完全信任, 在這之前我們還是得具有獨立思考的能力, AI僅是輔助我們快速思考的工具, 最終驗證與決策還是要回歸自身, 因此得到答案後也應一步步驗證再進行分享, 避免垃圾近、垃圾出的狀況導致誤解, 造成錯誤的結果。