XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/bilibili-API-collect

feat. wbi签名算法添加typescript实现 (#1031)

* feat. wbi签名算法添加typescript实现 * fix. Fixed missing quotes in User-Agent header in WBI JS demo

20940ee
xrz <62951481+xrz-cloud@users.noreply.github.com>
提交于

代码差异

1 个文件 +99 -3
Modified docs/misc/sign/wbi.md +99 -3
@@ -201,7 +201,10 @@ bar=514&baz=1919810&foo=114&wts=1702204169&w_rid=d3cbd2a2316089117134038bf4caf44
201 201
202 202 ### JavaScript
203 203
204 需要 `axios`、`md5` 依赖
204 需要 `fetch`(浏览器、NodeJS等环境自带)、`md5` 依赖
205
206 <CodeGroup>
207 <CodeGroupItem title="JavaScript">
205 208
206 209 ```javascript
207 210 import md5 from 'md5'
@@ -244,8 +247,8 @@ async function getWbiKeys() {
244 247 const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
245 248 headers: {
246 249 // SESSDATA 字段
247 Cookie: "SESSDATA=xxxxxx",
248 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',
250 Cookie: 'SESSDATA=xxxxxx',
251 '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',
249 252 Referer: 'https://www.bilibili.com/'//对于直接浏览器调用可能不适用
250 253 }
251 254 })
@@ -275,6 +278,99 @@ async function main() {
275 278 main()
276 279 ```
277 280
281 </CodeGroupItem>
282
283 <CodeGroupItem title="TypeScript">
284
285 ```typescript
286 import md5 from 'md5'
287
288 const mixinKeyEncTab = [
289 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
290 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
291 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
292 36, 20, 34, 44, 52
293 ]
294
295 // 对 imgKey 和 subKey 进行字符顺序打乱编码
296 const getMixinKey = (orig: string) =>
297 mixinKeyEncTab
298 .map((n) => orig[n])
299 .join("")
300 .slice(0, 32);
301
302 // 为请求参数进行 wbi 签名
303 function encWbi(
304 params: { [key: string]: string | number | object },
305 img_key: string,
306 sub_key: string
307 ) {
308 const mixin_key = getMixinKey(img_key + sub_key),
309 curr_time = Math.round(Date.now() / 1000),
310 chr_filter = /[!'()*]/g;
311
312 Object.assign(params, { wts: curr_time }); // 添加 wts 字段
313 // 按照 key 重排参数
314 const query = Object.keys(params)
315 .sort()
316 .map((key) => {
317 // 过滤 value 中的 "!'()*" 字符
318 const value = params[key].toString().replace(chr_filter, "");
319 return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
320 })
321 .join("&");
322
323 const wbi_sign = md5(query + mixin_key); // 计算 w_rid
324
325 return query + "&w_rid=" + wbi_sign;
326 }
327 // 获取最新的 img_key 和 sub_key
328 async function getWbiKeys(SESSDATA: string) {
329 const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
330 headers: {
331 // SESSDATA 字段
332 Cookie: `SESSDATA=${SESSDATA}`,
333 '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',
334 Referer: 'https://www.bilibili.com/'//对于直接浏览器调用可能不适用
335 }
336 })
337 const {
338 data: {
339 wbi_img: { img_url, sub_url },
340 },
341 } = (await res.json()) as {
342 data: {
343 wbi_img: { img_url: string; sub_url: string };
344 };
345 };
346
347 return {
348 img_key: img_url.slice(
349 img_url.lastIndexOf('/') + 1,
350 img_url.lastIndexOf('.')
351 ),
352 sub_key: sub_url.slice(
353 sub_url.lastIndexOf('/') + 1,
354 sub_url.lastIndexOf('.')
355 )
356 }
357 }
358
359 async function main() {
360 const web_keys = await getWbiKeys("SESSDATA的值")
361 const params = { foo: '114', bar: '514', baz: 1919810 },
362 img_key = web_keys.img_key,
363 sub_key = web_keys.sub_key
364 const query = encWbi(params, img_key, sub_key)
365 console.log(query)
366 }
367
368 main()
369 ```
370
371 </CodeGroupItem>
372 </CodeGroup>
373
278 374 输出内容为进行 Wbi 签名的后参数的 url query 形式
279 375
280 376 ```