SocialSisterYi / bilibili-API-collect

哔哩哔哩-API收集整理【不断更新中....】
https://socialsisteryi.github.io/bilibili-API-collect/
Other
15.27k stars 1.73k forks source link

`w_webid` related discovery #1107

Open cxw620 opened 2 months ago

cxw620 commented 2 months ago

[WARNING] DO NOT LEAK YOUR PRIVACY INFO! [注意] 注意你的隐私信息, 评论时注意码掉, 包括但不限于 Cookie, access_key 等!

Notice new param w_webid for risk controlling usage. See https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104

Intro

w_webid is a string acting as JSON Web Token (JWT), whose payload contains fingerprinting and tracking info, see the example:

{
  "spm_id": "0.0", // SPM ID
  "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", // UA
  "created_at": 1726929227, // jwt is created at
  "ttl": 86400, // jwt valid time
  "url": "***", // Path
  "result": "normal", // ?
  "iss": "gaia", // this jwt is issued by GAIA Risk control gateway
  "iat": 1726929227 // jwt is issued at
}

Signing ALG is HS256.

Source

See js file: https://s1.hdslb.com/bfs/static/jinkela/space/9.space.287534f1741242b75d48126d84e7bef2bb8877c8.js

image

Similar to WBI signing, w_webid also plays the same role.

How to get it

Access the HTML directly and get from HTML content:

Search for <script id="__RENDER_DATA__" type="application/json">***</script> then URLDecode ***, we will get a json string and inner access_id is what we need.

image

Notice

JWT cannot be faked since we do not know the private key. However, attaching this to the HTML itself instead of serving an REST API may cause perf regression and will such regression be accepted? I don't know.

Last updated: 24/09/21 23:11

Originally posted by @cxw620 in https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104#discussioncomment-10713345

QHCT commented 1 month ago

直接获取html,访问频繁的话经常会遇到弹验证码的情况,如果做自动化操作的时候还是很影响的

c-basalt commented 1 month ago

@QHCT JWT的TTL是一天(事实上网页里还有一个setTimeout自动在快到期的时候刷新网页),应该不需要反复访问刷新?

Seaurchin486 commented 1 month ago

api.bilibili.com/x/space/wbi/acc/info 这个接口在原有wbi签名基础上加上w_webid依然报错,返回-404。 似乎还需要额外的校验。 从网页复制的请求如下: https://api.bilibili.com/x/space/wbi/acc/info? mid=97203360& token=& platform=web& web_location=1550101& dm_img_list=[]& dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ& dm_cover_img_str=QU5HTEUgKEFNRCwgQU1EIFJhZGVvbiBSWCA3OTAwIFhUWCAoMHgwMDAwNzQ0QykgRGlyZWN0M0QxMSB2c181XzAgcHNfNV8wLCBEM0QxMSlHb29nbGUgSW5jLiAoQU1EKQ& dm_img_inter=%7B%22ds%22:[],%22wh%22:[4297,3549,81],%22of%22:[327,654,327]%7D& w_webid=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzcG1faWQiOiIwLjAiLCJidXZpZCI6IjU3RDM0RDUwLUZDNkEtMEUzNy1BNEI3LTQzNTAzODExRDU3RDcwNDY1aW5mb2MiLCJ1c2VyX2FnZW50IjoiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzEyOS4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMjkuMC4wLjAiLCJidXZpZF9mcCI6IjBkZjQxYTc5NGQ2OTIwMzU1M2FjYTQwOGRhMjNiN2YxIiwiYmlsaV90aWNrZXQiOiJkY2FmZDYxOTQwZDYyNWFjYTM0NDNlNGZhM2E3NTdkMyIsImNyZWF0ZWRfYXQiOjE3MjgyNjQyOTgsInR0bCI6ODY0MDAsInVybCI6Ii85NzIwMzM2MD9zcG1faWRfZnJvbT0zMzMuMTAwNy4wLjAiLCJyZXN1bHQiOiJub3JtYWwiLCJpc3MiOiJnYWlhIiwiaWF0IjoxNzI4MjY0Mjk4fQ.ZrJ_g2qvJfMETepQgT08ZVI7lhYEHL0otlgWPb59q6D9hhLN_UrKXCCJOnwOoSvmKalfWP-JQG3YKOilBaVQTnVaXoAWNSR2dLFMyM6suewqKI58wDGwM3hPh6xyQbRXQ-3Xkdhc-7uQLk_wwKMvQG2a0aKMgEDLkGbBRqLtlYpwQzz6zbPBB7RioATX6Hq9n1NvkcYD7dzs9C0bUQEKI07Czwtw2xEuHeA8I_vzSuGgscCOcTSg6rqxM32DLRMxCuxtPAmUzhUKLmScNLtifnOOTF1rssr_bj-0XNfP58kmE0BMjMYy7adHDQMhWK4KzW8UmYeVF7G7It1CQ8e1lA& w_rid=aae5e53ab9aa656dd8d16adff01e1aae& wts=1728264301

QHCT commented 1 month ago

我试了返回403,{"code":-403,"message":"访问权限不足","ttl":1},用了浏览器提取的cookie也不行

o0HalfLife0o commented 1 month ago

b站真的是无可救药了,不想着优化推流算法,成天折腾这些乱七八糟的参数

lovegaoshi commented 1 month ago

我真是曹乐 b站闲着没事儿干能不能喝点西北风阿

js & cheerio实现:https://github.com/lovegaoshi/azusa-player-mobile/pull/590/commits/f4113996f4b1fc30e6a2964e40ef914a8c745810#diff-83ff38add308188f73aa86d9fd6c89ada413eb4f34903c2c14c08653edc31c0a

z0z0r4 commented 1 month ago

Python & httpx 实现

import httpx
import re
import urllib.parse
import json
import time
from functools import reduce
from hashlib import md5

UID = 3546729368520811

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Referer": "https://www.bilibili.com/",
    "Cookie": "<cookie>",
}

dynamic_url = f"https://space.bilibili.com/{UID}/dynamic"

text = httpx.get(dynamic_url, headers=headers).text

# <script id="__RENDER_DATA__" type="application/json">xxx</script>
__RENDER_DATA__ = re.search(
    r"<script id=\"__RENDER_DATA__\" type=\"application/json\">(.*?)</script>",
    text,
    re.S,
).group(1)

access_id = json.loads(urllib.parse.unquote(__RENDER_DATA__))["access_id"]

print(f'access_id: {access_id}')

# wbi 签名
mixinKeyEncTab = [
    46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
    33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
    61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
    36, 20, 34, 44, 52
]

def getMixinKey(orig: str):
    "对 imgKey 和 subKey 进行字符顺序打乱编码"
    return reduce(lambda s, i: s + orig[i], mixinKeyEncTab, "")[:32]

def encWbi(params: dict, img_key: str, sub_key: str):
    "为请求参数进行 wbi 签名"
    mixin_key = getMixinKey(img_key + sub_key)
    curr_time = round(time.time())
    params["wts"] = curr_time  # 添加 wts 字段
    params = dict(sorted(params.items()))  # 按照 key 重排参数
    # 过滤 value 中的 "!'()*" 字符
    params = {
        k: "".join(filter(lambda chr: chr not in "!'()*", str(v)))
        for k, v in params.items()
    }
    query = urllib.parse.urlencode(params)  # 序列化参数
    wbi_sign = md5((query + mixin_key).encode()).hexdigest()  # 计算 w_rid
    params["w_rid"] = wbi_sign
    return params

def getWbiKeys() -> tuple[str, str]:
    "获取最新的 img_key 和 sub_key"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
        "Referer": "https://www.bilibili.com/",
    }
    resp = httpx.get("https://api.bilibili.com/x/web-interface/nav", headers=headers)
    resp.raise_for_status()
    json_content = resp.json()
    img_url: str = json_content["data"]["wbi_img"]["img_url"]
    sub_url: str = json_content["data"]["wbi_img"]["sub_url"]
    img_key = img_url.rsplit("/", 1)[1].split(".")[0]
    sub_key = sub_url.rsplit("/", 1)[1].split(".")[0]
    return img_key, sub_key

img_key, sub_key = getWbiKeys()

# mid=3546729368520811&web_location=333.999&w_webid=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzcG1faWQiOiIwLjAiLCJidXZpZCI6IjQxNjdDMjIwLTY4RDAtOTIxMS05RkQyLUY2OTc2MTQ5QzU0NzYzODE5aW5mb2MiLCJ1c2VyX2FnZW50Ijoi7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzEzMC4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xMzAuMC4wLjAiLCJidXZpZF9mcCI6Ijk3ZTYxZDdjMTQ2ZTJmM2M4MWIyNjRmMTgzYThmMDI3IiwiYmlsaV90aWNrZXQiOiI3YzdkNGY4M2Q5NWY3MDU3MWFhM2E0OGY3ZDhiOWU2MyIsImNyZWF0ZWRfYXQiOjE3MjkzNzgwNTAsInR0bCI6ODY0MDAsInVybCI6Ii8zNTQ2NzI5MzY4NTIwODExL2R5bmFtaWMiLCJyZXN1bHQiOiJub3JtYWwiLCJpc3MiOiJnYWlhIiwiaWF0IjoxNzI5Mzc4MDUwfQ.Bsq7sOO0U8kJqiOIRDQdAQTsFshUFaQTt1be8m0B8fRHCfPik00Qszt3ja8vjI-7huBp1we2HHHf4QyhydmMXHTsQTYT55Gy1Y1AK3JlEndnoG42Q3sxnz2n1lp7Rne49vPUzh0wmjCC1CLqNY9_Wj3ZGSYhrotRqyDKC_cFMH8MZoWSIftVrC7JrI9Kt31jym9N4F70R4HdzNzROndhHxismIA9dtBRQtzhF2BARiIyRDrfFRazfHFrCU9piD0Axf4612KNtBjK808Rym03RfA2mXELZNJGjW8TCfZOjdPsHCutH-gMOnbfSjFPbgrWUeUI3CNy9zbKbUODyry6tw&w_rid=608d77c216b277cd196651eb4c6be538
signed_params = encWbi(
    params={
        "mid": UID,
        "web_location": 333.999,
        "w_webid": access_id,
    },
    img_key=img_key,
    sub_key=sub_key,
)
query = urllib.parse.urlencode(signed_params)

relation_url = "https://api.bilibili.com/x/space/wbi/acc/relation"

resp = httpx.get(f"{relation_url}?{query}", headers=headers)

print(resp.json())

access_id: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzcG1faWQiOiIwLjAiLCJidXZpZCI6IjQxNjdDMjIwLTY4RDAtOTIxMS05RkQyLUY2OTc2MTQ5QzU0NzYzODE5aW5mb2MiLCJ1c2VyX2FnZW50IjoiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzU4LjAuMzAyOS4xMTAgU2FmYXJpLzUzNy4zIiwiYnV2aWRfZnAiOiI5N2U2MWQ3Yz******************************pYSIsImlhdCI6MTcyOTM3OTcxNn0.DF1OyasMK5T5UqwvcMbH1id7P-Fqp0KeI594m1jONUpCff7Fd37x3taCg7WJxr32D9SznCBMQ-Yh7gQJbWx3fL_fRSIzCV32xke2W-GGstfDT68Zgl-Vgw_r5DNb2oaR1x43amcIHbXe_XwQPnWvYm3kRpsh9rBJN4N_r9D63zObim6CbWPmdA5HVrhsWoPucRxLeEkjmbc8mQSGg64EIDYy0rkmJX9JvGMBQyMBNiYRUF4yjTLj_smFGZh8YU0Rfc0Lhbj9wzW_CWcfjx2n770ZVDmZgJ-5j1zZBZhtk7KDG8q0WOGFhgijUi55ZuMluSHjG38EfaVyj8TgVW_gew
{'code': 0, 'message': '0', 'ttl': 1, 'data': {'relation': {'mid': 3546729368520811, 'attribute': 2, 'mtime': 1722900958, 'tag': None, 'special': 0}, 'be_relation': {'mid': 0, 'attribute': 0, 'mtime': 0, 'tag': None, 'special': 0}}}
dawnsummit commented 1 month ago

b站真的是无可救药了,不想着优化推流算法,成天折腾这些乱七八糟的参数

说明人浮于事,无事可干。这些风控的意义在哪里?

z0z0r4 commented 4 weeks ago

防 AI 训练爬虫?虽然不认为B站有高价值的数据...我倒是看到不少爬虫单子,毕竟知乎不登录都不少限制了

snowtafir commented 3 weeks ago

接口 https://api.bilibili.com/x/space/wbi/acc/info 报错 -403 访问权限不足

import axios from 'axios';
import lodash from 'lodash';

async function getUserInfoByUid(uid) {
    const url = 'https://api.bilibili.com/x/space/wbi/acc/info'
    const cookie = 'buvid3=073B762A-2483-F772-FFD5-978C07FDB70C31024infoc; b_nut=1729935831; b_lsid=1036B363E_192C8886C89; _uuid=753712DA-9F36-16C2-5576-54F1DD3A7DE632710infoc; buvid_fp=ac842ef66c103bfa08b4a4bc2dc142fe; buvid4=786BA3FD-AAFE-649F-27E6-9270CAC7880432017-024102609-XM%2FRk2K47ksyOJCAXfjskQ%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTUwMzIsImlhdCI6MTcyOTkzNTc3MiwicGx0IjotMX0.nCEWWOa_m7--9sQaH-rM3K4XTk5KxxpaVFgia14S-hk; bili_ticket_expires=1730194972'
    const data = {
        mid: uid,
        token: '',
        platform: 'web',
        web_location: 1550101,
        dm_img_list: [],
        dm_img_str: 'V2ViR0wgMS',
        dm_cover_img_str: 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApLCBvciBzaW1pbGFyR29vZ2xlIEluYy4gKEludGVsKQ';

    };
    const w_webid = await getWebId(uid); //获取方法 https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104
    const { w_rid, time_stamp } = await getWbiSign(data, cookie); //具体算法 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
    const params = {
        ...data,
        w_webid: w_webid,
        w_rid: w_rid,
        wts: time_stamp
    };
    const res = await axios.get(url, {
        params,
        timeout: 5000,
        headers: {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Accept-Language': 'zh-CN,en-US;q=0.5',
            'Connection': 'keep-alive',
            'Priority': 'u=0, i',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Sec-GPC': '1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
            Cookie: `${cookie}`,
            Host: `api.bilibili.com`,
            Origin: 'https://space.bilibili.com',
            Referer: `https://space.bilibili.com/${uid}/dynamic`
        }
    });
    return res;
}

(async () => {
    const resp = await getUserInfoByUid(401742377);
    const data = resp.data
    console.log(`${JSON.stringify(data)}`);
})();

大致运行,结果返回

{"code":-403,"message":"访问权限不足","ttl":1}

如果缺省 w_webid 值,则直接返回

{"code":-352,"message":"风控校验失败","ttl":1,"data":{"v_voucher":"voucher_23cxxxx6-f634-4xxf-863a-dxxxxxxx"}}

不知有没有解决的

wuziqian211 commented 3 weeks ago

接口 https://api.bilibili.com/x/space/wbi/acc/info 报错 -403 访问权限不足

import axios from 'axios';
import lodash from 'lodash';

async function getUserInfoByUid(uid) {
    const url = 'https://api.bilibili.com/x/space/wbi/acc/info'
    const cookie = 'buvid3=073B762A-2483-F772-FFD5-978C07FDB70C31024infoc; b_nut=1729935831; b_lsid=1036B363E_192C8886C89; _uuid=753712DA-9F36-16C2-5576-54F1DD3A7DE632710infoc; buvid_fp=ac842ef66c103bfa08b4a4bc2dc142fe; buvid4=786BA3FD-AAFE-649F-27E6-9270CAC7880432017-024102609-XM%2FRk2K47ksyOJCAXfjskQ%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTUwMzIsImlhdCI6MTcyOTkzNTc3MiwicGx0IjotMX0.nCEWWOa_m7--9sQaH-rM3K4XTk5KxxpaVFgia14S-hk; bili_ticket_expires=1730194972'
    const data = {
        mid: uid,
        token: '',
        platform: 'web',
        web_location: 1550101,
        dm_img_list: [],
        dm_img_str: 'V2ViR0wgMS',
        dm_cover_img_str: 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApLCBvciBzaW1pbGFyR29vZ2xlIEluYy4gKEludGVsKQ';

    };
    const w_webid = await getWebId(uid); //获取方法 https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104
    const { w_rid, time_stamp } = await getWbiSign(data, cookie); //具体算法 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
    const params = {
        ...data,
        w_webid: w_webid,
        w_rid: w_rid,
        wts: time_stamp
    };
    const res = await axios.get(url, {
        params,
        timeout: 5000,
        headers: {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Accept-Language': 'zh-CN,en-US;q=0.5',
            'Connection': 'keep-alive',
            'Priority': 'u=0, i',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Sec-GPC': '1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
            Cookie: `${cookie}`,
            Host: `api.bilibili.com`,
            Origin: 'https://space.bilibili.com',
            Referer: `https://space.bilibili.com/${uid}/dynamic`
        }
    });
    return res;
}

(async () => {
    const resp = await getUserInfoByUid(401742377);
    const data = resp.data
    console.log(`${JSON.stringify(data)}`);
})();

大致运行,结果返回

{"code":-403,"message":"访问权限不足","ttl":1}

如果缺省 w_webid 值,则直接返回

{"code":-352,"message":"风控校验失败","ttl":1,"data":{"v_voucher":"voucher_23cxxxx6-f634-4xxf-863a-dxxxxxxx"}}

不知有没有解决的

wtsw_webid 参数也需要传递到 getWbiSign() 函数中,并且编码后的参数只需要额外添加 w_rid 参数就行了

另外目前来看,-403 错误码只会在 w_rid 计算错误时出现

z0z0r4 commented 3 weeks ago

@cxw620 能否麻烦在每次新建此类 issue 时,在顶部以标题的方式,标注注意数据脱敏的 tips?

上传任何信息时请注意脱敏,删去账户密码、敏感 cookies 等可能泄漏个人信息的数据(例如 SESSDATA、bili_jct 之类的 cookies)

snowtafir commented 3 weeks ago

接口 https://api.bilibili.com/x/space/wbi/acc/info 报错 -403 访问权限不足

import axios from 'axios';
import lodash from 'lodash';

async function getUserInfoByUid(uid) {
    const url = 'https://api.bilibili.com/x/space/wbi/acc/info'
    const cookie = 'buvid3=073B762A-2483-F772-FFD5-978C07FDB70C31024infoc; b_nut=1729935831; b_lsid=1036B363E_192C8886C89; _uuid=753712DA-9F36-16C2-5576-54F1DD3A7DE632710infoc; buvid_fp=ac842ef66c103bfa08b4a4bc2dc142fe; buvid4=786BA3FD-AAFE-649F-27E6-9270CAC7880432017-024102609-XM%2FRk2K47ksyOJCAXfjskQ%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTUwMzIsImlhdCI6MTcyOTkzNTc3MiwicGx0IjotMX0.nCEWWOa_m7--9sQaH-rM3K4XTk5KxxpaVFgia14S-hk; bili_ticket_expires=1730194972'
    const data = {
        mid: uid,
        token: '',
        platform: 'web',
        web_location: 1550101,
        dm_img_list: [],
        dm_img_str: 'V2ViR0wgMS',
        dm_cover_img_str: 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApLCBvciBzaW1pbGFyR29vZ2xlIEluYy4gKEludGVsKQ';

    };
    const w_webid = await getWebId(uid); //获取方法 https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104
    const { w_rid, time_stamp } = await getWbiSign(data, cookie); //具体算法 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
    const params = {
        ...data,
        w_webid: w_webid,
        w_rid: w_rid,
        wts: time_stamp
    };
    const res = await axios.get(url, {
        params,
        timeout: 5000,
        headers: {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Accept-Language': 'zh-CN,en-US;q=0.5',
            'Connection': 'keep-alive',
            'Priority': 'u=0, i',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Sec-GPC': '1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
            Cookie: `${cookie}`,
            Host: `api.bilibili.com`,
            Origin: 'https://space.bilibili.com',
            Referer: `https://space.bilibili.com/${uid}/dynamic`
        }
    });
    return res;
}

(async () => {
    const resp = await getUserInfoByUid(401742377);
    const data = resp.data
    console.log(`${JSON.stringify(data)}`);
})();

大致运行,结果返回

{"code":-403,"message":"访问权限不足","ttl":1}

如果缺省 w_webid 值,则直接返回

{"code":-352,"message":"风控校验失败","ttl":1,"data":{"v_voucher":"voucher_23cxxxx6-f634-4xxf-863a-dxxxxxxx"}}

不知有没有解决的

wtsw_webid 参数也需要传递到 getWbiSign() 函数中,并且编码后的参数只需要额外添加 w_rid 参数就行了

另外目前来看,-403 错误码只会在 w_rid 计算错误时出现

已解决,感谢❤

okatu-loli commented 2 weeks ago

接口 https://api.bilibili.com/x/space/wbi/acc/info 报错 -403 访问权限不足

import axios from 'axios';
import lodash from 'lodash';

async function getUserInfoByUid(uid) {
    const url = 'https://api.bilibili.com/x/space/wbi/acc/info'
    const cookie = 'buvid3=073B762A-2483-F772-FFD5-978C07FDB70C31024infoc; b_nut=1729935831; b_lsid=1036B363E_192C8886C89; _uuid=753712DA-9F36-16C2-5576-54F1DD3A7DE632710infoc; buvid_fp=ac842ef66c103bfa08b4a4bc2dc142fe; buvid4=786BA3FD-AAFE-649F-27E6-9270CAC7880432017-024102609-XM%2FRk2K47ksyOJCAXfjskQ%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTUwMzIsImlhdCI6MTcyOTkzNTc3MiwicGx0IjotMX0.nCEWWOa_m7--9sQaH-rM3K4XTk5KxxpaVFgia14S-hk; bili_ticket_expires=1730194972'
    const data = {
        mid: uid,
        token: '',
        platform: 'web',
        web_location: 1550101,
        dm_img_list: [],
        dm_img_str: 'V2ViR0wgMS',
        dm_cover_img_str: 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApLCBvciBzaW1pbGFyR29vZ2xlIEluYy4gKEludGVsKQ';

    };
    const w_webid = await getWebId(uid); //获取方法 https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104
    const { w_rid, time_stamp } = await getWbiSign(data, cookie); //具体算法 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
    const params = {
        ...data,
        w_webid: w_webid,
        w_rid: w_rid,
        wts: time_stamp
    };
    const res = await axios.get(url, {
        params,
        timeout: 5000,
        headers: {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Accept-Language': 'zh-CN,en-US;q=0.5',
            'Connection': 'keep-alive',
            'Priority': 'u=0, i',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Sec-GPC': '1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
            Cookie: `${cookie}`,
            Host: `api.bilibili.com`,
            Origin: 'https://space.bilibili.com',
            Referer: `https://space.bilibili.com/${uid}/dynamic`
        }
    });
    return res;
}

(async () => {
    const resp = await getUserInfoByUid(401742377);
    const data = resp.data
    console.log(`${JSON.stringify(data)}`);
})();

大致运行,结果返回

{"code":-403,"message":"访问权限不足","ttl":1}

如果缺省 w_webid 值,则直接返回

{"code":-352,"message":"风控校验失败","ttl":1,"data":{"v_voucher":"voucher_23cxxxx6-f634-4xxf-863a-dxxxxxxx"}}

不知有没有解决的

wtsw_webid 参数也需要传递到 getWbiSign() 函数中,并且编码后的参数只需要额外添加 w_rid 参数就行了 另外目前来看,-403 错误码只会在 w_rid 计算错误时出现

已解决,感谢❤

@snowtafir 您好,我也遇到了{"code":-403,"message":"访问权限不足","ttl":1}的问题,请问您是如何解决的,方便的话可以贴一下代码吗?

wuziqian211 commented 2 weeks ago

接口 https://api.bilibili.com/x/space/wbi/acc/info 报错 -403 访问权限不足

import axios from 'axios';
import lodash from 'lodash';

async function getUserInfoByUid(uid) {
    const url = 'https://api.bilibili.com/x/space/wbi/acc/info'
    const cookie = 'buvid3=073B762A-2483-F772-FFD5-978C07FDB70C31024infoc; b_nut=1729935831; b_lsid=1036B363E_192C8886C89; _uuid=753712DA-9F36-16C2-5576-54F1DD3A7DE632710infoc; buvid_fp=ac842ef66c103bfa08b4a4bc2dc142fe; buvid4=786BA3FD-AAFE-649F-27E6-9270CAC7880432017-024102609-XM%2FRk2K47ksyOJCAXfjskQ%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzAxOTUwMzIsImlhdCI6MTcyOTkzNTc3MiwicGx0IjotMX0.nCEWWOa_m7--9sQaH-rM3K4XTk5KxxpaVFgia14S-hk; bili_ticket_expires=1730194972'
    const data = {
        mid: uid,
        token: '',
        platform: 'web',
        web_location: 1550101,
        dm_img_list: [],
        dm_img_str: 'V2ViR0wgMS',
        dm_cover_img_str: 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApLCBvciBzaW1pbGFyR29vZ2xlIEluYy4gKEludGVsKQ';

    };
    const w_webid = await getWebId(uid); //获取方法 https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1104
    const { w_rid, time_stamp } = await getWbiSign(data, cookie); //具体算法 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
    const params = {
        ...data,
        w_webid: w_webid,
        w_rid: w_rid,
        wts: time_stamp
    };
    const res = await axios.get(url, {
        params,
        timeout: 5000,
        headers: {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'Accept-Language': 'zh-CN,en-US;q=0.5',
            'Connection': 'keep-alive',
            'Priority': 'u=0, i',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Sec-GPC': '1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
            Cookie: `${cookie}`,
            Host: `api.bilibili.com`,
            Origin: 'https://space.bilibili.com',
            Referer: `https://space.bilibili.com/${uid}/dynamic`
        }
    });
    return res;
}

(async () => {
    const resp = await getUserInfoByUid(401742377);
    const data = resp.data
    console.log(`${JSON.stringify(data)}`);
})();

大致运行,结果返回

{"code":-403,"message":"访问权限不足","ttl":1}

如果缺省 w_webid 值,则直接返回

{"code":-352,"message":"风控校验失败","ttl":1,"data":{"v_voucher":"voucher_23cxxxx6-f634-4xxf-863a-dxxxxxxx"}}

不知有没有解决的

wtsw_webid 参数也需要传递到 getWbiSign() 函数中,并且编码后的参数只需要额外添加 w_rid 参数就行了 另外目前来看,-403 错误码只会在 w_rid 计算错误时出现

已解决,感谢❤

@snowtafir 您好,我也遇到了{"code":-403,"message":"访问权限不足","ttl":1}的问题,请问您是如何解决的,方便的话可以贴一下代码吗?

目前只有 w_rid 计算错误或者留空的情况下才返回 -403 错误码,您可以检查一下所有参数(除了 w_rid 参数本身)是否都经过了编码

z0z0r4 commented 1 week ago

我建议一切 wbi 有问题都自查去...别在这问

有帖子专门讨论 wbi 鉴权的吧