WebSocket 握手是一个从 HTTP 协议升级到 WebSocket 协议的过程,通过 HTTP Upgrade 机制实现。
握手流程详解
1. 客户端发起握手请求
客户端发送一个特殊的 HTTP GET 请求,包含以下关键头部字段:
shellGET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
关键头部说明:
Upgrade: websocket: 告诉服务器客户端想要升级到 WebSocket 协议Connection: Upgrade: 表示这是一个升级连接Sec-WebSocket-Key: 客户端生成的随机字符串,用于验证服务器Sec-WebSocket-Version: WebSocket 协议版本,当前为 13Sec-WebSocket-Protocol: 可选,指定子协议Sec-WebSocket-Extensions: 可选,指定扩展功能
2. 服务器验证并响应
服务器收到请求后,进行以下验证:
- 验证
Sec-WebSocket-Key是否存在 - 将
Sec-WebSocket-Key与 GUID258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接 - 对拼接后的字符串进行 SHA-1 哈希
- 将哈希结果进行 Base64 编码
- 将编码结果放入
Sec-WebSocket-Accept头部
服务器响应:
shellHTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
3. 连接建立成功
服务器返回 101 状态码后,HTTP 连接升级为 WebSocket 连接,双方开始使用 WebSocket 数据帧进行通信。
握手安全性
防止跨站 WebSocket 劫持(CSWSH)
Origin头部验证:服务器检查请求来源Sec-WebSocket-Key验证:防止缓存投毒攻击
最佳实践
- 使用 WSS(WebSocket Secure)加密连接
- 验证
Origin头部 - 实施适当的认证机制
- 限制连接频率