百趣云 百趣云的博客

B站扫码登录协议:从 qrcode_key 到 SESSDATA

B站扫码登录的接口设计

B站的扫码登录是各家里最规整的——接口语义清晰、无复杂加密,是理解扫码登录协议的最佳样本。核心目标:拿到 SESSDATA cookie(B站登录态的灵魂)。

全流程拆解

第一步:申请二维码

GET https://passport.bilibili.com/x/passport-login/web/qrcode/generate

返回:

{
  "data": {
    "url": "https://passport.bilibili.com/h5-app/passport/login/scan?...qrcode_key=xxx",
    "qrcode_key": "a1b2c3d4..."
  }
}

url 做成二维码展示(App 扫的就是它),qrcode_key 是后续轮询的凭证。

第二步:轮询扫码状态

GET https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=xxx

返回码含义:

  • 86101:未扫码
  • 86090:已扫码,待确认
  • 86038:二维码已过期
  • 0:确认登录成功——此时响应头 Set-Cookie 里有 SESSDATA,同时 data.url 是跳转地址(老接口兼容)

第三步(可选):跳转激活

部分场景需要再 GET 一次 data.url 完成 cookie 的完整落地。用 Session 跟一次跳转即可。

完整实现

import requests, time, qrcode

class BiliQRLogin:
    def __init__(self):
        self.s = requests.Session()
        self.s.headers['User-Agent'] = 'Mozilla/5.0 ...'

    def login(self):
        # 1. 申请二维码
        r = self.s.get('https://passport.bilibili.com/x/passport-login/web/qrcode/generate')
        data = r.json()['data']
        qrcode_key, url = data['qrcode_key'], data['url']

        # 2. 展示二维码(命令行打印或生成图片)
        qr = qrcode.QRCode()
        qr.add_data(url)
        qr.print_ascii(invert=True)

        # 3. 轮询
        while True:
            time.sleep(2)
            r = self.s.get('https://passport.bilibili.com/x/passport-login/web/qrcode/poll',
                           params={'qrcode_key': qrcode_key})
            code = r.json()['data']['code']
            if code == 0:
                print('登录成功')
                return self.s.cookies.get('SESSDATA')
            elif code == 86038:
                print('二维码过期')
                return None
            elif code == 86090:
                print('已扫码,待确认')

精髓:SESSDATA 的使用与维护

  1. SESSDATA 是长期凭证(有效期约 30 天),但它只是登录 cookie 组合的核心——完整可用态还需要 bili_jct(CSRF token,写操作必备)、buvid3(设备标识)、DedeUserID(uid)
  2. bili_jct 参与表单校验:POST 写操作(点赞、评论、投币)要带 csrf=bili_jct的值,从 cookie 取
  3. SESSDATA 有 IP 绑定倾向:频繁异地使用会触发"账号异常"验证。账号池里 SESSDATA 和 IP 段绑定
  4. 刷新机制:B站有 refresh_token 体系(refresh_csrf/refresh_token 接口),SESSDATA 快过期时无感刷新,别等失效了重新扫码

风控点

扫码登录接口本身风控宽松,但新登录态的"考察期"要注意:刚登录的会话立刻高频调接口,容易触发验证。登录后先访问几个页面接口"养"几分钟,再上业务请求。

总结

  1. 流程:generate 拿 qrcode_key → poll 轮询 → code=0 时收 SESSDATA
  2. 状态码 86101/86090/86038/0 对应等待/已扫/过期/成功
  3. SESSDATA + bili_jct + buvid3 是完整登录态,写操作要 csrf
  4. 新登录态有考察期,先养再用

交流微信:run1255

By 百趣云 阅读量:24 On