v0.5.5: 应急页 v0.5.4 + 移除IT设备升级 + admin登录修复 + 内容审核架构 + 知识库
This commit is contained in:
+12
-11
@@ -20,7 +20,6 @@
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
||||
from starlette.requests import Request
|
||||
|
||||
from app.services.ws_manager import manager as ws_manager
|
||||
from app.services.cache_service import cache_service
|
||||
@@ -39,7 +38,6 @@ WS_CLOSE_UNAUTHORIZED = 4001
|
||||
async def websocket_endpoint(
|
||||
websocket: WebSocket,
|
||||
agent_id: str,
|
||||
request: Request,
|
||||
) -> None:
|
||||
"""坐席 WebSocket 端点主循环(含 WS-01 token 认证)。
|
||||
|
||||
@@ -61,10 +59,12 @@ async def websocket_endpoint(
|
||||
- 兼容从 ?token= URL 参数获取(向后兼容)
|
||||
- 不再将 token 暴露在 URL 中,避免 access_log 泄露
|
||||
|
||||
v0.5.1 修复:移除 `request: Request` 参数(部分 Starlette 版本注入 Request 失败,
|
||||
改用 `websocket.headers` 和 `websocket.query_params` 读取 header/query)
|
||||
|
||||
Args:
|
||||
websocket: FastAPI WebSocket 对象(框架自动注入)
|
||||
agent_id: 坐席ID(从 URL 路径参数获取)
|
||||
request: Starlette Request(用于获取 header)
|
||||
"""
|
||||
# ======================================================================
|
||||
# WS-01: Token 认证(从 subprotocol / header / query 获取)
|
||||
@@ -74,17 +74,17 @@ async def websocket_endpoint(
|
||||
# 格式: 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", "")
|
||||
subprotocol = websocket.headers.get("sec-websocket-protocol", "")
|
||||
if subprotocol.startswith("bearer."):
|
||||
token = subprotocol[7:] # 去掉 "bearer." 前缀
|
||||
else:
|
||||
# 其次从 Authorization header 获取
|
||||
auth_header = request.headers.get("Authorization", "")
|
||||
auth_header = websocket.headers.get("Authorization", "")
|
||||
if auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:] # 去掉 "Bearer " 前缀
|
||||
else:
|
||||
# 向后兼容:从 query param 获取(即将废弃)
|
||||
token = request.query_params.get("token", "")
|
||||
token = websocket.query_params.get("token", "")
|
||||
|
||||
# 步骤2: 检查 token 是否为空
|
||||
if not token:
|
||||
@@ -197,7 +197,6 @@ async def websocket_endpoint(
|
||||
async def h5_websocket_endpoint(
|
||||
websocket: WebSocket,
|
||||
employee_id: str,
|
||||
request: Request,
|
||||
) -> None:
|
||||
"""H5员工 WebSocket 端点主循环(含 token 认证)。
|
||||
|
||||
@@ -223,10 +222,12 @@ async def h5_websocket_endpoint(
|
||||
- (与H5登录 API /api/h5/mock-login 存储格式一致)
|
||||
- token 缺失、无效、过期、与 employee_id 不匹配均拒绝连接
|
||||
|
||||
v0.5.1 修复:移除 `request: Request` 参数(部分 Starlette 版本注入 Request 失败,
|
||||
改用 `websocket.headers` 和 `websocket.query_params` 读取 header/query)
|
||||
|
||||
Args:
|
||||
websocket: FastAPI WebSocket 对象(框架自动注入)
|
||||
employee_id: 员工企微 UserID(从 URL 路径参数获取)
|
||||
request: Starlette Request(用于获取 header)
|
||||
"""
|
||||
# ======================================================================
|
||||
# Token 认证(从 subprotocol / header / query 获取)
|
||||
@@ -234,17 +235,17 @@ async def h5_websocket_endpoint(
|
||||
|
||||
# 步骤1: 优先从 Sec-WebSocket-Protocol (subprotocol) 获取 token,其次从 Authorization header,最后从 query(向后兼容)
|
||||
# 格式: Sec-WebSocket-Protocol: bearer.{token}
|
||||
subprotocol = request.headers.get("sec-websocket-protocol", "")
|
||||
subprotocol = websocket.headers.get("sec-websocket-protocol", "")
|
||||
if subprotocol.startswith("bearer."):
|
||||
token = subprotocol[7:] # 去掉 "bearer." 前缀
|
||||
else:
|
||||
# 其次从 Authorization header 获取
|
||||
auth_header = request.headers.get("Authorization", "")
|
||||
auth_header = websocket.headers.get("Authorization", "")
|
||||
if auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:] # 去掉 "Bearer " 前缀
|
||||
else:
|
||||
# 向后兼容:从 query param 获取(即将废弃)
|
||||
token = request.query_params.get("token", "")
|
||||
token = websocket.query_params.get("token", "")
|
||||
|
||||
# 步骤2: 检查 token 是否为空
|
||||
if not token:
|
||||
|
||||
Reference in New Issue
Block a user