Files
live-hub-py/core/douyu/login_api_iframe.py
T
2026-06-26 17:22:51 +08:00

118 lines
3.9 KiB
Python

"""iframe 版登录接口策略"""
import time
import urllib.parse
from .crypto import encrypt_nickname_or_phone, encrypt_password
from .login_api import LoginAPIStrategy
class IframeLoginAPI(LoginAPIStrategy):
"""iframe 版接口策略
使用旧版 iframe 接口,参数嵌套结构,用户名 RC4 加密后 URL 编码。
第一次登录使用 wgapi 接口获取极验参数,第二次登录使用 iframe 接口。
"""
# e 语言中硬编码的 did 值
DEFAULT_DID = "6ab33184203a7d50d5f9a8fa00021701"
@property
def name(self) -> str:
return "iframe"
@property
def first_login_url(self) -> str:
"""第一次登录用 wgapi 接口获取极验参数"""
return "https://passport.douyu.com/wgapi/member/passport/login"
@property
def login_url(self) -> str:
"""第二次登录用 iframe 接口"""
return "https://passport.douyu.com/iframe/loginNew"
@property
def send_email_url(self) -> str:
return "https://passport.douyu.com/iframe/sendEmail"
@property
def verify_url(self) -> str:
return "https://passport.douyu.com/iframe/remoteLogin"
def encrypt_username(self, username: str) -> str:
"""RC4 加密后 URL 编码"""
encrypted = encrypt_nickname_or_phone(username)
return urllib.parse.quote(encrypted, safe='')
def build_first_login_data(self, username: str, password: str, referer: str) -> dict:
"""构建第一次登录参数(获取极验参数)
注:第一次登录使用 wgapi 接口,所以用户名用 base64 编码(而非 URL 编码)。
"""
# 第一次登录用 wgapi 接口,需要 base64 编码的用户名
encrypted_username = encrypt_nickname_or_phone(username)
return {
'type': '1',
'nicknameOrPhoneEncrypt': encrypted_username,
'password': encrypt_password(password),
'biz_type': '1',
'room_id': '0',
'redirect_url': referer,
't': str(int(time.time() * 1000)),
'client_id': '1',
'did': '',
'lang': '',
'isMultiAccount': '0',
}
def build_second_login_data(
self,
username: str,
password: str,
gt: str,
challenge: str,
validate: str,
seccode: str,
code_token: str,
referer: str,
) -> dict:
"""构建第二次登录参数(带极验验证)
使用 iframe 接口的嵌套参数结构。
注意:iframe 接口使用 username 参数(直接用户名URL编码),而非 nicknameOrPhoneEncrypt。
"""
# seccode 格式: validate|jordan
seccode_value = validate + '%7Cjordan'
return {
'username': username, # iframe 接口用 username,直接用户名
'password': encrypt_password(password),
'room_id': '0',
'code_verify_data[code_type]': '1',
'code_verify_data[code_token]': code_token,
'code_verify_data[code_data][geetest_challenge]': challenge,
'code_verify_data[code_data][geetest_validate]': validate,
'code_verify_data[code_data][geetest_seccode]': seccode_value,
'code_verify_data[code_data][gt_version]': 'v3',
'redirect_url': referer,
't': str(int(time.time() * 1000)),
'client_id': '1',
'did': '',
'lang': '',
'isMultiAccount': '0',
}
def build_send_email_data(self, code: str) -> dict:
"""构建发送邮箱验证参数"""
return {'cacheId': code}
def build_verify_data(self, code: str, captcha: str) -> dict:
"""构建提交验证码参数"""
return {
'veify_type': '2', # e 语言原文如此,斗鱼接口拼写
'phoneCaptcha': captcha,
'client_id': '1',
'isMultiAccount': '0',
'cacheId': code,
}