P0安全修复: WS token改subprotocol + nginx日志关闭 + 类型修复 + 降级验证 + 依赖

This commit is contained in:
Simon
2026-06-14 21:21:48 +08:00
parent edbb86835e
commit ddebbe61a5
12 changed files with 628 additions and 27 deletions
+28 -16
View File
@@ -67,17 +67,24 @@ async def websocket_endpoint(
request: Starlette Request(用于获取 header
"""
# ======================================================================
# WS-01: Token 认证(从 header query 获取)
# WS-01: Token 认证(从 subprotocol / header / query 获取)
# ======================================================================
# 步骤1: 优先从 Authorization header 获取 token,其次从 query(向后兼容)
# 格式: Authorization: Bearer {token}
auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("Bearer "):
token = auth_header[7:] # 去掉 "Bearer " 前缀
# 步骤1: 优先从 Sec-WebSocket-Protocol (subprotocol) 获取 token,其次从 Authorization header,最后从 query(向后兼容)
# 格式: Sec-WebSocket-Protocol: bearer.{token}
# 说明: 浏览器原生 WebSocket API 不支持 headers 参数,但支持 subprotocols (第2参数数组)
# 前端用 new WebSocket(url, ["bearer.{token}"]) 传递,服务端从 sec-websocket-protocol 头读取
subprotocol = request.headers.get("sec-websocket-protocol", "")
if subprotocol.startswith("bearer."):
token = subprotocol[7:] # 去掉 "bearer." 前缀
else:
# 向后兼容:从 query param 获取(即将废弃)
token = request.query_params.get("token", "")
# 其次从 Authorization header 获取
auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("Bearer "):
token = auth_header[7:] # 去掉 "Bearer " 前缀
else:
# 向后兼容:从 query param 获取(即将废弃)
token = request.query_params.get("token", "")
# 步骤2: 检查 token 是否为空
if not token:
@@ -222,17 +229,22 @@ async def h5_websocket_endpoint(
request: Starlette Request(用于获取 header
"""
# ======================================================================
# Token 认证(从 header query 获取)
# Token 认证(从 subprotocol / header / query 获取)
# ======================================================================
# 步骤1: 优先从 Authorization header 获取 token,其次从 query(向后兼容)
# 格式: Authorization: Bearer {token}
auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("Bearer "):
token = auth_header[7:] # 去掉 "Bearer " 前缀
# 步骤1: 优先从 Sec-WebSocket-Protocol (subprotocol) 获取 token,其次从 Authorization header,最后从 query(向后兼容)
# 格式: Sec-WebSocket-Protocol: bearer.{token}
subprotocol = request.headers.get("sec-websocket-protocol", "")
if subprotocol.startswith("bearer."):
token = subprotocol[7:] # 去掉 "bearer." 前缀
else:
# 向后兼容:从 query param 获取(即将废弃)
token = request.query_params.get("token", "")
# 其次从 Authorization header 获取
auth_header = request.headers.get("Authorization", "")
if auth_header.startswith("Bearer "):
token = auth_header[7:] # 去掉 "Bearer " 前缀
else:
# 向后兼容:从 query param 获取(即将废弃)
token = request.query_params.get("token", "")
# 步骤2: 检查 token 是否为空
if not token: