203 lines
54 KiB
JavaScript
203 lines
54 KiB
JavaScript
import{_ as t,c,a as o,b as s,d as a,e,w as p,r,o as i}from"./app-Dgsdh8A6.js";const D={};function y(d,n){const l=r("RouteLink");return i(),c("div",null,[n[21]||(n[21]=o(`<h1 id="biliticket" tabindex="-1"><a class="header-anchor" href="#biliticket"><span>BiliTicket</span></a></h1><h2 id="简述" tabindex="-1"><a class="header-anchor" href="#简述"><span>简述</span></a></h2><p><code>bili_ticket</code> 位于请求头 Cookie 中, 非必需, 但存在可降低风控概率</p><p>由 <a href="https://github.com/aynuarance" target="_blank" rel="noopener noreferrer">@aynuarance</a> 于 <a href="https://github.com/SocialSisterYi/bilibili-API-collect/issues/903" target="_blank" rel="noopener noreferrer">#903</a> 提供的思路,根据时间戳使用 <code>hmac_sha256</code> 算法计算 <code>hexsign</code>。</p><p>是 <a href="https://jwt.io/" target="_blank" rel="noopener noreferrer">JWT 令牌</a>,有效时长为 259260 秒,即 3 天。 例如 <code>eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDI3NDI3NDYsImlhdCI6MTcwMjQ4MzQ4NiwicGx0IjotMX0.xQgtTAc41NA1gzvd9yKUPgucUy_DKcQj6OG1vj8V7ZA</code></p><div class="language-json line-numbers-mode" data-highlighter="shiki" data-ext="json" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-json"><span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "alg"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"HS256"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "kid"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"s03"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "typ"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"JWT"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="算法" tabindex="-1"><a class="header-anchor" href="#算法"><span>算法</span></a></h2><ol><li>获取 UNIX 秒级时间戳存入变量如 <code>timestamp</code></li><li>计算变量 <code>hexsign</code> 值,使用 <code>hmac_sha256</code> 算法,密钥为 <code>XgwSnGZ1p</code>,消息为字符串 <code>"ts"</code> 与变量 <code>timestamp</code> 值拼接</li><li>构造请求参数,<code>key_id</code> 为 <code>ec02</code>,<code>hexsign</code> 为变量 <code>hexsign</code> 值,<code>context[ts]</code> 为变量 <code>timestamp</code> 值,<code>csrf</code> 为 cookie 中的 <code>bili_jct</code> 值也可为空</li><li>发送 <code>POST</code> 请求,获取 <code>data</code> 字段中的 <code>ticket</code> 字段的值即为所求</li></ol><h2 id="接口" tabindex="-1"><a class="header-anchor" href="#接口"><span>接口</span></a></h2><blockquote><p>https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket</p></blockquote><p><em>请求方式: POST</em></p><p>鉴权方式: 请求头 <code>Referer</code> 为空或 <code>.bilibili.com</code> 子域下任意页</p><p><strong>URL参数:</strong></p><table><thead><tr><th>参数名</th><th>类型</th><th>内容</th><th>必要性</th><th>备注</th></tr></thead><tbody><tr><td>key_id</td><td>str</td><td>ec02</td><td>必要</td><td></td></tr><tr><td>hexsign</td><td>str</td><td>由 <code>hmac_sha256</code> 算法计算的 <code>hexsign</code> 值</td><td>必要</td><td></td></tr><tr><td>context[ts]</td><td>num</td><td>UNIX 秒级时间戳</td><td>必要</td><td></td></tr><tr><td>csrf</td><td>str</td><td>cookie 中的 <code>bili_jct</code> 值</td><td>非必要</td><td></td></tr></tbody></table><p><strong>JSON回复:</strong></p><p>根对象:</p><table><thead><tr><th>字段</th><th>类型</th><th>内容</th><th>备注</th></tr></thead><tbody><tr><td>code</td><td>num</td><td>返回值</td><td>0: 成功<br>400: 参数错误</td></tr><tr><td>message</td><td>str</td><td>返回消息</td><td>OK: 成功</td></tr><tr><td>data</td><td>obj</td><td>数据本体</td><td></td></tr><tr><td>ttl</td><td>num</td><td>1</td><td></td></tr></tbody></table><p><code>data</code> 对象:</p>`,18)),s("table",null,[n[9]||(n[9]=s("thead",null,[s("tr",null,[s("th",null,"字段"),s("th",null,"类型"),s("th",null,"内容"),s("th",null,"备注")])],-1)),s("tbody",null,[n[5]||(n[5]=s("tr",null,[s("td",null,"ticket"),s("td",null,"str"),s("td",null,"bili_ticket"),s("td")],-1)),n[6]||(n[6]=s("tr",null,[s("td",null,"created_at"),s("td",null,"num"),s("td",null,"创建时间"),s("td",null,"UNIX 秒级时间戳")],-1)),n[7]||(n[7]=s("tr",null,[s("td",null,"ttl"),s("td",null,"num"),s("td",null,"有效时长"),s("td",null,"259200 秒 (3 天)")],-1)),n[8]||(n[8]=s("tr",null,[s("td",null,"context"),s("td",null,"obj"),s("td",null,"空"),s("td")],-1)),s("tr",null,[n[2]||(n[2]=s("td",null,"nav",-1)),n[3]||(n[3]=s("td",null,"obj",-1)),n[4]||(n[4]=s("td",null,"wbi_img 相关",-1)),s("td",null,[n[1]||(n[1]=a("参见 ")),e(l,{to:"/docs/misc/sign/wbi.html"},{default:p(()=>n[0]||(n[0]=[a("WBI 签名")])),_:1,__:[0]})])])])]),n[22]||(n[22]=s("p",null,[s("code",null,"nav"),a(" 对象:")],-1)),s("table",null,[n[20]||(n[20]=s("thead",null,[s("tr",null,[s("th",null,"字段"),s("th",null,"类型"),s("th",null,"内容"),s("th",null,"备注")])],-1)),s("tbody",null,[s("tr",null,[n[12]||(n[12]=s("td",null,"img",-1)),n[13]||(n[13]=s("td",null,"str",-1)),n[14]||(n[14]=s("td",null,"img_key 值",-1)),s("td",null,[n[11]||(n[11]=a("参见 ")),e(l,{to:"/docs/misc/sign/wbi.html"},{default:p(()=>n[10]||(n[10]=[a("WBI 签名")])),_:1,__:[10]})])]),s("tr",null,[n[17]||(n[17]=s("td",null,"sub",-1)),n[18]||(n[18]=s("td",null,"str",-1)),n[19]||(n[19]=s("td",null,"sub_key 值",-1)),s("td",null,[n[16]||(n[16]=a("参见 ")),e(l,{to:"/docs/misc/sign/wbi.html"},{default:p(()=>n[15]||(n[15]=[a("WBI 签名")])),_:1,__:[15]})])])])]),n[23]||(n[23]=o(`<p><strong>示例:</strong></p><details><summary>查看响应示例:</summary><div class="language-json line-numbers-mode" data-highlighter="shiki" data-ext="json" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-json"><span class="line"><span style="color:#D4D4D4;">{</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "code"</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">0</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "message"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"OK"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "data"</span><span style="color:#D4D4D4;">: {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "ticket"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjM2OTMwODAsImlhdCI6MTcyMzQzMzgyMCwicGx0IjotMX0.efOwv7i4m0ykABrXEDHGAechU2AByMcP_-3EYpQrNKs"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "created_at"</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1723433820</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "ttl"</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">259200</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "context"</span><span style="color:#D4D4D4;">: {},</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "nav"</span><span style="color:#D4D4D4;">: {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "img"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"https://i0.hdslb.com/bfs/wbi/7cd084941338484aae1ad9425b84077c.png"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "sub"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"https://i0.hdslb.com/bfs/wbi/4932caff0ff746eab6f01bf08b70ac45.png"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> },</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> "ttl"</span><span style="color:#D4D4D4;">: </span><span style="color:#B5CEA8;">1</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><h2 id="demo" tabindex="-1"><a class="header-anchor" href="#demo"><span>Demo</span></a></h2><p>此处提供 <a href="#python">Python</a>, <a href="#java">Java</a>, <a href="#javascript-nodejs">JavaScript (Node.js)</a> 的示例代码</p><h3 id="python" tabindex="-1"><a class="header-anchor" href="#python"><span>Python</span></a></h3><p>需要 <code>requests</code> 依赖</p><div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-python"><span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> hmac</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> hashlib</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> requests</span></span>
|
||
<span class="line"><span style="color:#C586C0;">import</span><span style="color:#D4D4D4;"> time</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">def</span><span style="color:#DCDCAA;"> hmac_sha256</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">message</span><span style="color:#D4D4D4;">):</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> """</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 使用HMAC-SHA256算法对给定的消息进行加密</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> :param key: 密钥</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> :param message: 要加密的消息</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> :return: 加密后的哈希值</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> """</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> # 将密钥和消息转换为字节串</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> key = key.encode(</span><span style="color:#CE9178;">'utf-8'</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> message = message.encode(</span><span style="color:#CE9178;">'utf-8'</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> # 创建HMAC对象,使用SHA256哈希算法</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> hmac_obj = hmac.new(key, message, hashlib.sha256)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> # 计算哈希值</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> hash_value = hmac_obj.digest()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> # 将哈希值转换为十六进制字符串</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> hash_hex = hash_value.hex()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#D4D4D4;"> hash_hex</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C586C0;">if</span><span style="color:#9CDCFE;"> __name__</span><span style="color:#D4D4D4;"> == </span><span style="color:#CE9178;">'__main__'</span><span style="color:#D4D4D4;">:</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> o = hmac_sha256(</span><span style="color:#CE9178;">"XgwSnGZ1p"</span><span style="color:#D4D4D4;">,</span><span style="color:#569CD6;">f</span><span style="color:#CE9178;">"ts</span><span style="color:#569CD6;">{</span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">(time.time())</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">)</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> url = </span><span style="color:#CE9178;">"https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> params = {</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "key_id"</span><span style="color:#D4D4D4;">:</span><span style="color:#CE9178;">"ec02"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "hexsign"</span><span style="color:#D4D4D4;">:o,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "context[ts]"</span><span style="color:#D4D4D4;">:</span><span style="color:#569CD6;">f</span><span style="color:#CE9178;">"</span><span style="color:#569CD6;">{</span><span style="color:#4EC9B0;">int</span><span style="color:#D4D4D4;">(time.time())</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">"</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "csrf"</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">''</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> headers = {</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'user-agent'</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> resp = requests.post(url, </span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">=params,</span><span style="color:#9CDCFE;">headers</span><span style="color:#D4D4D4;">=headers).json()</span></span>
|
||
<span class="line"><span style="color:#DCDCAA;"> print</span><span style="color:#D4D4D4;">(resp)</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="java" tabindex="-1"><a class="header-anchor" href="#java"><span>Java</span></a></h3><p>无需第三方依赖</p><div class="language-java line-numbers-mode" data-highlighter="shiki" data-ext="java" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-java"><span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.io.ByteArrayOutputStream;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.io.InputStream;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.net.HttpURLConnection;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.net.URI;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> java.nio.charset.StandardCharsets;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> javax.crypto.Mac;</span></span>
|
||
<span class="line"><span style="color:#569CD6;">import</span><span style="color:#D4D4D4;"> javax.crypto.spec.SecretKeySpec;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#569CD6;">public</span><span style="color:#569CD6;"> class</span><span style="color:#4EC9B0;"> BiliTicketDemo</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Convert a byte array to a hex string.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#9CDCFE;"> bytes</span><span style="color:#6A9955;"> The byte array to convert.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@return</span><span style="color:#6A9955;"> The hex string representation of the given byte array.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> bytesToHex</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">byte</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">bytes</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> StringBuilder</span><span style="color:#9CDCFE;"> sb</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> StringBuilder</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> for</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">byte</span><span style="color:#9CDCFE;"> b</span><span style="color:#C586C0;"> :</span><span style="color:#D4D4D4;"> bytes) {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> hex</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">Integer</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toHexString</span><span style="color:#D4D4D4;">(</span><span style="color:#B5CEA8;">0xff</span><span style="color:#D4D4D4;"> & b);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">hex</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">length</span><span style="color:#D4D4D4;">() == </span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> sb</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'0'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> sb</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(hex);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> sb</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toString</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Generate a HMAC-SHA256 hash of the given message string using the given key</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * string.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#9CDCFE;"> key</span><span style="color:#6A9955;"> The key string to use for the HMAC-SHA256 hash.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#9CDCFE;"> message</span><span style="color:#6A9955;"> The message string to hash.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@throws</span><span style="color:#4EC9B0;"> Exception</span><span style="color:#6A9955;"> If an error occurs during the HMAC-SHA256 hash generation.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@return</span><span style="color:#6A9955;"> The HMAC-SHA256 hash of the given message string using the given key</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * string.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> hmacSha256</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> key</span><span style="color:#D4D4D4;">, </span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> message</span><span style="color:#D4D4D4;">) </span><span style="color:#569CD6;">throws</span><span style="color:#4EC9B0;"> Exception</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> Mac</span><span style="color:#9CDCFE;"> mac</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">Mac</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getInstance</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"HmacSHA256"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> SecretKeySpec</span><span style="color:#9CDCFE;"> secretKeySpec</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> SecretKeySpec</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">key</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getBytes</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">StandardCharsets</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF_8</span><span style="color:#D4D4D4;">), </span><span style="color:#CE9178;">"HmacSHA256"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> mac</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">init</span><span style="color:#D4D4D4;">(secretKeySpec);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> byte</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">hash</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">mac</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">doFinal</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">message</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getBytes</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">StandardCharsets</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF_8</span><span style="color:#D4D4D4;">));</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#DCDCAA;"> bytesToHex</span><span style="color:#D4D4D4;">(hash);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Get a Bilibili web ticket for the given CSRF token.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#9CDCFE;"> csrf</span><span style="color:#6A9955;"> The CSRF token to use for the web ticket, can be {@code null} or</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * empty.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@return</span><span style="color:#6A9955;"> The Bilibili web ticket raw response for the given CSRF token.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@throws</span><span style="color:#4EC9B0;"> Exception</span><span style="color:#6A9955;"> If an error occurs during the web ticket generation.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@see</span><span style="color:#6A9955;"> https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/bili_ticket.md</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> String</span><span style="color:#DCDCAA;"> getBiliTicket</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#9CDCFE;"> csrf</span><span style="color:#D4D4D4;">) </span><span style="color:#569CD6;">throws</span><span style="color:#4EC9B0;"> Exception</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // params</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> long</span><span style="color:#9CDCFE;"> ts</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">System</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">currentTimeMillis</span><span style="color:#D4D4D4;">() / </span><span style="color:#B5CEA8;">1000</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> String</span><span style="color:#9CDCFE;"> hexSign</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">hmacSha256</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"XgwSnGZ1p"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"ts"</span><span style="color:#D4D4D4;"> + ts);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> StringBuilder</span><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> StringBuilder</span><span style="color:#D4D4D4;">(</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> "https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'?'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"key_id=ec02"</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'&'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"hexsign="</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(hexSign).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'&'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"context[ts]="</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(ts).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'&'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"csrf="</span><span style="color:#D4D4D4;">).</span><span style="color:#DCDCAA;">append</span><span style="color:#D4D4D4;">(csrf == </span><span style="color:#569CD6;">null</span><span style="color:#C586C0;"> ?</span><span style="color:#CE9178;"> ""</span><span style="color:#C586C0;"> :</span><span style="color:#D4D4D4;"> csrf);</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> // request</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> HttpURLConnection</span><span style="color:#9CDCFE;"> conn</span><span style="color:#D4D4D4;"> = (HttpURLConnection) </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> URI</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">url</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toString</span><span style="color:#D4D4D4;">()).</span><span style="color:#DCDCAA;">toURL</span><span style="color:#D4D4D4;">().</span><span style="color:#DCDCAA;">openConnection</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> conn</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">setRequestMethod</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"POST"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> conn</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">addRequestProperty</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">"User-Agent"</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> InputStream</span><span style="color:#9CDCFE;"> in</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">conn</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">getInputStream</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> ByteArrayOutputStream</span><span style="color:#9CDCFE;"> out</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">new</span><span style="color:#DCDCAA;"> ByteArrayOutputStream</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#4EC9B0;"> int</span><span style="color:#9CDCFE;"> b</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> while</span><span style="color:#D4D4D4;"> ((b = </span><span style="color:#9CDCFE;">in</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">read</span><span style="color:#D4D4D4;">()) != -</span><span style="color:#B5CEA8;">1</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">write</span><span style="color:#D4D4D4;">(b);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#C586C0;"> new</span><span style="color:#DCDCAA;"> String</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toByteArray</span><span style="color:#D4D4D4;">(), </span><span style="color:#9CDCFE;">StandardCharsets</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">UTF_8</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;"> /**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Main method to test the BiliTicketDemo class.</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#9CDCFE;"> args</span><span style="color:#6A9955;"> The command line arguments (not used).</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> public</span><span style="color:#569CD6;"> static</span><span style="color:#4EC9B0;"> void</span><span style="color:#DCDCAA;"> main</span><span style="color:#D4D4D4;">(</span><span style="color:#4EC9B0;">String</span><span style="color:#D4D4D4;">[] </span><span style="color:#9CDCFE;">args</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> try</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> System</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">out</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">println</span><span style="color:#D4D4D4;">(</span><span style="color:#DCDCAA;">getBiliTicket</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">""</span><span style="color:#D4D4D4;">)); </span><span style="color:#6A9955;">// use empty CSRF here</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#C586C0;">catch</span><span style="color:#D4D4D4;"> (</span><span style="color:#4EC9B0;">Exception</span><span style="color:#9CDCFE;"> e</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> e</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">printStackTrace</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="javascript-node-js" tabindex="-1"><a class="header-anchor" href="#javascript-node-js"><span>JavaScript (Node.js)</span></a></h3><div class="language-javascript line-numbers-mode" data-highlighter="shiki" data-ext="javascript" style="background-color:#1E1E1E;color:#D4D4D4;"><pre class="shiki dark-plus vp-code"><code class="language-javascript"><span class="line"><span style="color:#569CD6;">const</span><span style="color:#4FC1FF;"> crypto</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">require</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'crypto'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">/**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Generate HMAC-SHA256 signature</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#4EC9B0;"> {string}</span><span style="color:#9CDCFE;"> key</span><span style="color:#6A9955;"> The key string to use for the HMAC-SHA256 hash</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#4EC9B0;"> {string}</span><span style="color:#9CDCFE;"> message</span><span style="color:#6A9955;"> The message string to hash</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@returns</span><span style="color:#4EC9B0;"> {string}</span><span style="color:#6A9955;"> The HMAC-SHA256 signature as a hex string</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;">function</span><span style="color:#DCDCAA;"> hmacSha256</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">key</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">message</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> hmac</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">crypto</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">createHmac</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'sha256'</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">key</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> hmac</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">update</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">message</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> hmac</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">digest</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'hex'</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#6A9955;">/**</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * Get Bilibili web ticket</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@param</span><span style="color:#4EC9B0;"> {string}</span><span style="color:#9CDCFE;"> csrf</span><span style="color:#6A9955;"> CSRF token, can be empty or null</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> * </span><span style="color:#569CD6;">@returns</span><span style="color:#4EC9B0;"> {Promise<any>}</span><span style="color:#6A9955;"> Promise of the ticket response in JSON format</span></span>
|
||
<span class="line"><span style="color:#6A9955;"> */</span></span>
|
||
<span class="line"><span style="color:#569CD6;">async</span><span style="color:#569CD6;"> function</span><span style="color:#DCDCAA;"> getBiliTicket</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">csrf</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> ts</span><span style="color:#D4D4D4;"> = </span><span style="color:#9CDCFE;">Math</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">floor</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">Date</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">now</span><span style="color:#D4D4D4;">() / </span><span style="color:#B5CEA8;">1000</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> hexSign</span><span style="color:#D4D4D4;"> = </span><span style="color:#DCDCAA;">hmacSha256</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'XgwSnGZ1p'</span><span style="color:#D4D4D4;">, </span><span style="color:#CE9178;">\`ts</span><span style="color:#569CD6;">\${</span><span style="color:#9CDCFE;">ts</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">\`</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> url</span><span style="color:#D4D4D4;"> = </span><span style="color:#CE9178;">'https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket'</span><span style="color:#D4D4D4;">;</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> params</span><span style="color:#D4D4D4;"> = </span><span style="color:#569CD6;">new</span><span style="color:#DCDCAA;"> URLSearchParams</span><span style="color:#D4D4D4;">({</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> key_id:</span><span style="color:#CE9178;"> 'ec02'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> hexsign:</span><span style="color:#9CDCFE;"> hexSign</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'context[ts]'</span><span style="color:#9CDCFE;">:</span><span style="color:#9CDCFE;"> ts</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> csrf:</span><span style="color:#9CDCFE;"> csrf</span><span style="color:#D4D4D4;"> || </span><span style="color:#CE9178;">''</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> });</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> response</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">await</span><span style="color:#DCDCAA;"> fetch</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">\`</span><span style="color:#569CD6;">\${</span><span style="color:#9CDCFE;">url</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">?</span><span style="color:#569CD6;">\${</span><span style="color:#9CDCFE;">params</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">toString</span><span style="color:#D4D4D4;">()</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">\`</span><span style="color:#D4D4D4;">, {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> method:</span><span style="color:#CE9178;"> 'POST'</span><span style="color:#D4D4D4;">,</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> headers:</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#CE9178;"> 'User-Agent'</span><span style="color:#9CDCFE;">:</span><span style="color:#CE9178;"> 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0'</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> });</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> if</span><span style="color:#D4D4D4;"> (!</span><span style="color:#9CDCFE;">response</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">ok</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> throw</span><span style="color:#569CD6;"> new</span><span style="color:#DCDCAA;"> Error</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">\`HTTP error! status: </span><span style="color:#569CD6;">\${</span><span style="color:#9CDCFE;">response</span><span style="color:#D4D4D4;">.</span><span style="color:#9CDCFE;">status</span><span style="color:#569CD6;">}</span><span style="color:#CE9178;">\`</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> return</span><span style="color:#9CDCFE;"> response</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">json</span><span style="color:#D4D4D4;">();</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#D4D4D4;">(</span><span style="color:#569CD6;">async</span><span style="color:#D4D4D4;"> () </span><span style="color:#569CD6;">=></span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#C586C0;"> try</span><span style="color:#D4D4D4;"> {</span></span>
|
||
<span class="line"><span style="color:#569CD6;"> const</span><span style="color:#4FC1FF;"> ticketResponse</span><span style="color:#D4D4D4;"> = </span><span style="color:#C586C0;">await</span><span style="color:#DCDCAA;"> getBiliTicket</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">''</span><span style="color:#D4D4D4;">); </span><span style="color:#6A9955;">// use empty CSRF here</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> console</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">log</span><span style="color:#D4D4D4;">(</span><span style="color:#9CDCFE;">ticketResponse</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> } </span><span style="color:#C586C0;">catch</span><span style="color:#D4D4D4;"> (</span><span style="color:#9CDCFE;">e</span><span style="color:#D4D4D4;">) {</span></span>
|
||
<span class="line"><span style="color:#9CDCFE;"> console</span><span style="color:#D4D4D4;">.</span><span style="color:#DCDCAA;">error</span><span style="color:#D4D4D4;">(</span><span style="color:#CE9178;">'Failed to get BiliTicket:'</span><span style="color:#D4D4D4;">, </span><span style="color:#9CDCFE;">e</span><span style="color:#D4D4D4;">);</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;"> }</span></span>
|
||
<span class="line"><span style="color:#D4D4D4;">})();</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div>`,12))])}const u=t(D,[["render",y]]),v=JSON.parse('{"path":"/docs/misc/sign/bili_ticket.html","title":"BiliTicket","lang":"zh-CN","frontmatter":{},"git":{"updatedTime":1738952932000,"contributors":[{"name":"z0z0r4","username":"z0z0r4","email":"z0z0r4@outlook.com","commits":1,"url":"https://github.com/z0z0r4"},{"name":"SessionHu","username":"SessionHu","email":"102411014+SessionHu@users.noreply.github.com","commits":3,"url":"https://github.com/SessionHu"}],"changelog":[{"hash":"7282aa2e358977efb84063a3ef67ccb6ed3d705f","time":1738952932000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"fix(bili_ticket.md): referer desc & nodejs code"},{"hash":"60a0c5d1a2f44fe61335da04571305fa7727a968","time":1724238159000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"feat: 各种接口补充与错误修正 (#1066)"},{"hash":"18c1efbc102ae6b44c8f5314c90e5e64f0d926cd","time":1721909032000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"feat: bili_ticket 算法 Java 实现 及 信息补充 及 错误修正 (#1061)"},{"hash":"180b8ce908d1abe02816c0ea89ddd1cfe6b3d7e6","time":1704853641000,"email":"z0z0r4@outlook.com","author":"z0z0r4","message":"feat: bili_ticket (#932)"}]},"filePathRelative":"docs/misc/sign/bili_ticket.md"}');export{u as comp,v as data};
|