Loading... 翰络云任务(yrw.hanloth.cn)里提供了B站签到功能,这个功能需要获取到账号的cookie。为了获取到cookie,我们写了登录获取cookie的页面。 涉及到了很多登录用的接口,在这里列一下,方便以后使用。 吐槽一句,为了抓取登录异常时手机号验证的完整api,用了我和我兄弟([@Scott_Sloan](https://sott.hanloth.cn))一共3个账号才搞到。这玩意儿不难,只是有点费账号。 另外,获取bilibili的cookie的网页版工具已经放在了 https://tool.hanloth.cn/bilibili_login 里,需要的可以直接使用 # 密码登录API ## 简述 使用密码登录分为以下几个步骤: 1.人机验证 2.密码加密 3.提交登录 (4.异常验证) ## 提交登录 #### 人机验证 接口:`https://passport.bilibili.com/x/passport-login/captcha` 方式:`GET` 参数: | 字段 | 类型 | 内容 | 备注 | | -------- | ------ | ---------------------------------------------------- | ------ | | source | str | `main_web`:独立登录页<br /> `main_mini`:小窗登录 | | | t | int | 时间戳 | | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | --------- | | code | num | 返回值 | 0:成功 | | message | str | 返回信息 | | | ttl | num | 1 | | | data | obj | 见下表 | | `data`对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------------- | ------------------------------------------------------- | | geetest | obj | 见下表 | | | tencent | obj | (?) | **作用尚不明确** | | token | str | 登录 API token | 与 captcha 无关,与登录接口有关 | | type | str | 验证方式 | 用于判断使用哪一种验证方式,目前所见只有geetest:极验 | `geetest`对象: | 字段 | 类型 | 内容 | 备注 | | ----------- | ------ | --------- | --------------------------- | | gt | str | 极验id | 一般为固定值 | | challenge | str | 极验KEY | 由B站后端产生用于人机验证 | [极验手动验证器](./#附录) #### 获取公钥和盐 接口:`http://passport.bilibili.com/x/passport-login/web/key` 方式:`GET` 参数: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | ------ | ------ | | 无 | 无 | 无 | 无 | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | --------- | | code | num | 返回值 | 0:成功 | | message | str | 错误信息 | | | ttl | num | 1 | | | data | obj | 见下表 | | `data`对象: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | ---------- | ------------------------------------------------------ | | hash | str | 密码盐值 | 有效时间为 20s``恒为 16 字符``需要拼接在明文密码之前 | | key | str | rsa 公钥 | `PEM 格式编码`加密密码时需要使用 | #### 密码加密 php中进行加密可以这么写: ```php $url = 'https://passport.bilibili.com/x/passport-login/web/key?_=164' . time(); $data = $this->curl($url); $arr = json_decode($data, true); openssl_public_encrypt($arr['data']['hash'] . $password, $encrypted, $arr['data']['key']); $result=base64_encode($encrypted); ``` 其中,`$password`为输入的密码,`$result`为最终加密后的密码 #### 提交登录 接口:`https://passport.bilibili.com/x/passport-login/web/login` 方式:`POST` 参数: | 参数名 | 类型 | 内容 | 必要性 | 备注 | | ----------- | ------ | ---------------------------------------------- | -------- | ------------------------------------------------------------- | | username | str | 用户登录账号 | 必要 | 手机号或邮箱地址 | | password | str | 加密后的带盐密码 | 必要 | base64 格式 | | keep | num | 0 | 必要 | | | token | str | 登录 token | 必要 | 申请人机验证时得到(data->token) | | challenge | str | 极验 challenge | 必要 | 申请人机验证时得到(data->geetest->challenge) | | validate | str | 极验 result | 必要 | 人机验证后得到(result->geetest_validate) | | seccode | str | 极验 result | 必要 | 人机验证后得到(result->geetest_seccode) | | go_url | str | 跳转 url | 非必要 | 默认为[https://www.bilibili.com](https://www.bilibili.com/) | | source | str | `main_web`:独立登录页 `main_mini`:小窗登录 | 非必要 | | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | num | 返回值 | 0:成功<br />-105:验证码错误<br /> -400:请求错误<br />-629:账号或密码错误<br /> -653:用户名或密码不能为空<br />-662:提交超时,请重新提交<br /> -2001:缺少必要的的参数<br />-2100:需验证手机号或邮箱<br /> 2400:登录秘钥错误<br />2406:验证极验服务出错<br />86000:RSA解密失败 | | message | str | 错误信息 | | | data | obj | 见下表 | | data 对象: | 字段 | 类型 | 内容 | 备注 | | --------------- | ------ | ---------------------- | ---------------------------------------- | | message | str | 状态信息 | | | refresh_token | str | 刷新`refresh_token` | | | status | num | 返回值 | 0:登录成功<br /><br />2:需要登录验证 | | timestamp | num | 登录时间 | 未登录为`0`时间戳 单位为毫秒 | | url | str | 游戏分站跨域登录 url | | ## 登录异常,手机号验证API 这个api网上没有人公开出来过,这里算得上首发了。 使用此处前,你应该已经完成登录操作。当在‘提交登录’步骤中取得的code为-2100,你才需要使用此处的接口。 此处放的响应值仅为后续所需要的响应值,并非全部响应值,不喜勿喷。 #### 数据处理 在进行验证前,需要先取出‘提交登录’返回值中data->url,解析url的query参数(GET方式提交的参数,位于网址末尾) #### 验证信息获取 接口:`https://api.bilibili.com/x/safecenter/user/info` 方式:`GET` 参数: | 字段 | 类型 | 内容 | 备注 | | ---------- | ------ | -------------- | --------------------------------------- | | tmp_code | str | 验证标记代码 | 来自数据处理中的解析出的参数tmp_token | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | -------- | ------ | | code | int | 0 | | | data | obj | 见下表 | | data对象: | 字段 | 类型 | 内容 | 备注 | | -------------- | ------ | -------- | ------ | | | | | | | account_info | obj | 见下表 | | account_info对象: | 字段 | 类型 | 内容 | 备注 | | ------------ | ------ | ------------------ | -------------------------- | | tel_verify | int | 1 | | | hide_tel | str | 需要验证的手机号 | 用星号隐藏了部分敏感信息 | #### 人机验证 接口:`https://passport.bilibili.com/x/safecenter/captcha/pre` 方式:`POST` 参数: | 字段 | 类型 | 内容 | | -------- | ------ | --------- | | source | str | main-fe | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | -------- | ------ | | code | int | 0 | | | data | obj | 见下表 | | data对象: | 字段 | 类型 | 内容 | 备注 | | ----------------- | ------ | ----------- | -------------------- | | gee_gt | str | 极验id | 用于创建极验验证码 | | gee_challenge | str | 极验key | 用于创建极验验证码 | | recaptcha_token | str | 验证token | | [极验手动验证器](./#附录) #### 申请验证码 接口:`https://passport.bilibili.com/x/safecenter/common/sms/send` 方式:`POST` 参数: | 字段 | 类型 | 内容 | 备注 | | ----------------- | ------ | --------------- | ------------------------------------------- | | sms_type | str | loginTelCheck | | | tmp_code | str | 验证标记代码 | 来自数据处理中的解析出的参数tmp_token | | gee_challenge | str | 极验id | 申请人机验证时得到(data->gee_challenge) | | gee_seccode | str | 极验key | 人机验证后得到(result->geetest_seccode) | | gee_validate | str | 极验result | 人机验证后得到(result->geetest_validate) | | recaptcha_token | str | 验证token | 申请人机验证时得到(data->recaptcha_token) | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | ------------------- | | code | int | 返回值 | 成功为0,失败为-1 | | data | obj | 见下表 | | | message | str | 错误信息 | | data对象: | 字段 | 类型 | 内容 | 备注 | | ------------- | ------ | ---------- | ------ | | captcha_key | str | 验证秘钥 | | #### 提交验证码 接口:`https://passport.bilibili.com/x/safecenter/login/tel/verify` 方式:`POST` 参数: | 字段 | 类型 | 内容 | 备注 | | ------------- | ------ | --------------- | -------------------------------------------------- | | type | str | loginTelCheck | | | code | int | 验证码内容 | | | tmp_code | str | 验证标记代码 | 来自数据处理中的解析出的参数tmp_token | | request_id | str | 验证请求标记 | 来自数据处理中的解析出的参数requestId | | captcha_key | str | 验证秘钥 | 来自申请验证码的captcha_key(data->captcha_key) | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | ------------------- | | code | int | 返回值 | 正确为0,错误为-1 | | message | str | 错误信息 | | | data | obj | 见下表 | | data对象: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | ---------- | ------ | | code | str | 交换代码 | | #### 交换获取cookie 接口:`https://passport.bilibili.com/x/passport-login/web/exchange_cookie` 方式:`POST` 参数: | 字段 | 类型 | 内容 | 备注 | | ------ | ------ | ---------- | ------------------------------ | | code | str | 交换代码 | 来自提交验证码(data->code) | 响应:(json) 根对象: | 字段 | 类型 | 内容 | 备注 | | --------- | ------ | ---------- | ------------------- | | code | int | 返回值 | 成功为0,失败为-1 | | message | str | 错误信息 | | 响应头: 设置许多cookie,示例: ```http HTTP/1.1 200 OK Date: Mon, 13 Jul 2020 06:56:00 GMT Content-Type: application/json;charset=UTF-8 Content-Length: 273 Connection: keep-alive Server: Apache-Coyote/1.1 Set-Cookie: DedeUserID=***; Domain=.bilibili.com; Expires=Sat, 09-Jan-2021 06:39:43 GMT; Path=/ Set-Cookie: DedeUserID__ckMd5=***; Domain=.bilibili.com; Expires=Sat, 09-Jan-2021 06:39:43 GMT; Path=/ Set-Cookie: SESSDATA=***; Domain=.bilibili.com; Expires=Sat, 09-Jan-2021 06:39:43 GMT; Path=/; HttpOnly Set-Cookie: bili_jct=***; Domain=.bilibili.com; Expires=Sat, 09-Jan-2021 06:39:43 GMT; Path=/ Content-Security-Policy-Report-Only: default-src 'self' data: *.bilibili.com *.hdslb.com; style-src 'self' 'unsafe-inline' *.hdslb.com static.geetest.com; img-src 'self' data: blob: *.bilibili.com *.hdslb.com http://*.hdslb.com static.geetest.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.bilibili.com *.hdslb.com api.geetest.com static.geetest.com; object-src 'self' *.hdslb.com; media-src 'self' *.acgvideo.com http://*.acgvideo.com *.ksyungslb.com; connect-src 'self' data: wss://*.bilibili.com:* *.bilibili.com *.hdslb.com *.biliapi.net *.biliapi.com; frame-ancestors 'self' *.bilibili.com *.biligame.com; report-uri https://security.bilibili.com/csp_report Expires: Mon, 13 Jul 2020 06:55:59 GMT Cache-Control: no-cache X-Cache-Webcdn: BYPASS from jd-sxhz-dx-w-01 ``` # 短信登录 正在努力编写 # 扫码登录 正在努力编写 # 附录 参考资料:https://github.com/SocialSisterYi/bilibili-API-collect [极验手动验证器](https://kuresaru.github.io/geetest-validator/) [及其源码](https://github.com/kuresaru/geetest-validator) : 1. 打开手动验证器,在1、2分别填入上面API返回的 `gt`和 `challenge` 2. 点击按钮3,稍等加载验证码,点击按钮4进行验证 3. 验证完成后,点击按钮5生成验证结果 4. 使用最开始获得到的 `key`、`challenge`和刚获得到的 `validate`、`seccode`继续之后的登录操作 Last modification:January 22, 2023 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 7 如果觉得我的文章对你有用,请随意赞赏