前端直连时认证包加上key

This commit is contained in:
John Smith 2024-03-21 00:02:58 +08:00
parent 891566222e
commit 409e61f8ef
2 changed files with 78 additions and 13 deletions

View File

@ -10,6 +10,7 @@ from typing import *
import aiohttp
import tornado.websocket
import yarl
import api.base
import blivedm.blivedm.clients.web as dm_web_cli
@ -327,23 +328,26 @@ class RoomInfoHandler(api.base.ApiHandler):
async def get(self):
room_id = int(self.get_query_argument('roomId'))
logger.info('client=%s getting room info, room=%d', self.request.remote_ip, room_id)
room_id, owner_uid = await self._get_room_info(room_id)
# 连接其他host必须要key
host_server_list = dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST
if owner_uid == 0:
# 缓存3分钟
self.set_header('Cache-Control', 'private, max-age=180')
else:
# 缓存1天
self.set_header('Cache-Control', 'private, max-age=86400')
(room_id, owner_uid), (host_server_list, host_server_token), buvid = await asyncio.gather(
self._get_room_info(room_id),
self._get_server_host_list_and_token(room_id),
self._get_buvid()
)
# 缓存1分钟
self.set_header('Cache-Control', 'private, max-age=60')
self.write({
'roomId': room_id,
'ownerUid': owner_uid,
'hostServerList': host_server_list
'hostServerList': host_server_list,
'hostServerToken': host_server_token,
# 虽然没什么用但还是加上比较保险
'buvid': buvid,
})
@staticmethod
async def _get_room_info(room_id):
async def _get_room_info(room_id) -> Tuple[int, int]:
try:
async with utils.request.http_session.get(
dm_web_cli.ROOM_INIT_URL,
@ -372,6 +376,61 @@ class RoomInfoHandler(api.base.ApiHandler):
room_info = data['data']['room_info']
return room_info['room_id'], room_info['uid']
async def _get_server_host_list_and_token(self, room_id) -> Tuple[dict, Optional[str]]:
try:
async with utils.request.http_session.get(
dm_web_cli.DANMAKU_SERVER_CONF_URL,
headers={
# token会对UA签名要使用和客户端一样的UA
'User-Agent': self.request.headers.get('User-Agent', '')
},
params={
'id': room_id,
'type': 0
}
) as res:
if res.status != 200:
logger.warning('room %d _get_server_host_list failed: %d %s', room_id,
res.status, res.reason)
return dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST, None
data = await res.json()
except (aiohttp.ClientConnectionError, asyncio.TimeoutError):
logger.exception('room %d _get_server_host_list failed', room_id)
return dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST, None
if data['code'] != 0:
logger.warning('room %d _get_server_host_list failed: %s', room_id, data['message'])
return dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST, None
data = data['data']
host_server_list = data['host_list']
if not host_server_list:
logger.warning('room %d _get_server_host_list failed: host_server_list is empty')
return dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST, None
host_server_token = data.get('token', None)
return host_server_list, host_server_token
async def _get_buvid(self):
buvid = self._do_get_buvid()
if buvid != '':
return buvid
try:
async with utils.request.http_session.get(dm_web_cli.BUVID_INIT_URL):
pass
except (aiohttp.ClientConnectionError, asyncio.TimeoutError):
pass
return self._do_get_buvid()
@staticmethod
def _do_get_buvid():
cookies = utils.request.http_session.cookie_jar.filter_cookies(yarl.URL(dm_web_cli.BUVID_INIT_URL))
buvid_cookie = cookies.get('buvid3', None)
if buvid_cookie is None:
return ''
return buvid_cookie.value
class AvatarHandler(api.base.ApiHandler):
async def get(self):

View File

@ -16,6 +16,8 @@ export default class ChatClientDirectWeb extends ChatClientOfficialBase {
this.hostServerList = [
{ host: "broadcastlv.chat.bilibili.com", port: 2243, wss_port: 443, ws_port: 2244 }
]
this.hostServerToken = null
this.buvid = ''
}
async initRoom() {
@ -32,6 +34,8 @@ export default class ChatClientDirectWeb extends ChatClientOfficialBase {
if (res.hostServerList.length !== 0) {
this.hostServerList = res.hostServerList
}
this.hostServerToken = res.hostServerToken
this.buvid = res.buvid
return true
}
@ -56,8 +60,10 @@ export default class ChatClientDirectWeb extends ChatClientOfficialBase {
protover: 3,
platform: 'web',
type: 2,
buvid: '',
// TODO B站开始检查key了有空时加上
buvid: this.buvid,
}
if (this.hostServerToken !== null) {
authParams.key = this.hostServerToken
}
this.websocket.send(this.makePacket(authParams, base.OP_AUTH))
}