From cb143479563fbdded4e73fbf295b0b27b245410f Mon Sep 17 00:00:00 2001 From: RRRosmontis Date: Sun, 6 Sep 2026 00:49:03 +0800 Subject: [PATCH] =?UTF-8?q?danmaku:=20WS=20join=20=E5=BC=BA=E5=88=B6=20liv?= =?UTF-8?q?e-token=20=E6=A0=A1=E9=AA=8C=E5=B9=B6=E9=94=81=E5=AE=9A?= =?UTF-8?q?=E6=98=B5=E7=A7=B0=EF=BC=88=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=20user=EF=BC=8C=E5=BF=BD=E7=95=A5=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E5=A3=B0=E6=98=8E=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- danmaku/danmaku_auth.json | 1 + danmaku/danmaku_backend.py | 44 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 danmaku/danmaku_auth.json diff --git a/danmaku/danmaku_auth.json b/danmaku/danmaku_auth.json new file mode 100644 index 0000000..3be69ef --- /dev/null +++ b/danmaku/danmaku_auth.json @@ -0,0 +1 @@ +{"verify_url": "https://api.rrrosmontis.icu/v1/live/api/auth/verify"} diff --git a/danmaku/danmaku_backend.py b/danmaku/danmaku_backend.py index d7e7630..a8dd68b 100755 --- a/danmaku/danmaku_backend.py +++ b/danmaku/danmaku_backend.py @@ -17,6 +17,34 @@ logging.basicConfig( ] ) logger = logging.getLogger("danmaku") +MSG_NO_LOGIN = "未登录,无法加入弹幕" +MSG_BAD_TOKEN = "登录已失效,请刷新页面重试" +NICK_GUEST = "观众" + +# ==================== 弹幕登录校验(live token -> live-api) ==================== +import os as _os +VERIFY_URL = 'https://api.rrrosmontis.icu/v1/live/api/auth/verify' +try: + _cfg = json.load(open(_os.path.join(_os.path.dirname(_os.path.abspath(__file__)), 'danmaku_auth.json'), encoding='utf-8')) + VERIFY_URL = _cfg.get('verify_url', VERIFY_URL) +except Exception: + pass + + +def _verify_token_sync(token): + try: + import urllib.request as _ur + req = _ur.Request(VERIFY_URL, data=json.dumps({'token': token}).encode('utf-8'), headers={'Content-Type': 'application/json'}) + with _ur.urlopen(req, timeout=6) as resp: + d = json.loads(resp.read().decode('utf-8')) + return d.get('user') if d.get('ok') else None + except Exception: + return None + + +async def _verify_token(token): + return await asyncio.to_thread(_verify_token_sync, token) + # ==================== 直播间类 ==================== class LiveRoom: @@ -56,6 +84,7 @@ app = FastAPI() async def websocket_endpoint(websocket: WebSocket): await websocket.accept() client_host = websocket.client.host if websocket.client else "unknown" + token = (websocket.query_params.get('token') or '').strip() logger.info(f"新WebSocket连接: {client_host}") current_room: LiveRoom = None @@ -82,8 +111,19 @@ async def websocket_endpoint(websocket: WebSocket): current_room.connections.discard(websocket) # 加入新房间 + # 登录校验: 弹幕连接必须携带有效 live token (?token=) + if not token: + await websocket.send_json({"type": "error", "message": MSG_NO_LOGIN}) + await websocket.close(code=4401) + return + user_info = await _verify_token(token) + if not user_info: + await websocket.send_json({"type": "error", "message": MSG_BAD_TOKEN}) + await websocket.close(code=4401) + return + current_room = await get_or_create_room(room_id) - current_user = data.get("user", "匿名") + current_user = user_info.get("nickname") or NICK_GUEST async with current_room.connections_lock: current_room.connections.add(websocket) @@ -106,7 +146,7 @@ async def websocket_endpoint(websocket: WebSocket): continue text = data.get("text", "") - user = data.get("user", current_user or "匿名") + user = current_user or NICK_GUEST danmaku = { "text": text, "user": user,