mirror of https://github.com/synctv-org/synctv
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
4.7 KiB
Go
181 lines
4.7 KiB
Go
package bilibili
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
json "github.com/json-iterator/go"
|
|
"github.com/synctv-org/synctv/utils"
|
|
)
|
|
|
|
type RQCode struct {
|
|
URL string `json:"url"`
|
|
Key string `json:"key"`
|
|
}
|
|
|
|
func NewQRCode(ctx context.Context) (*RQCode, error) {
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://passport.bilibili.com/x/passport-login/web/qrcode/generate", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Referer", "https://passport.bilibili.com/login")
|
|
req.Header.Set("User-Agent", utils.UA)
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
qr := qrcodeResp{}
|
|
err = json.NewDecoder(resp.Body).Decode(&qr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// TODO: error message
|
|
return &RQCode{
|
|
URL: qr.Data.URL,
|
|
Key: qr.Data.QrcodeKey,
|
|
}, nil
|
|
}
|
|
|
|
// return SESSDATA cookie
|
|
func LoginWithQRCode(ctx context.Context, key string) (*http.Cookie, error) {
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=%s", key), nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Referer", "https://passport.bilibili.com/login")
|
|
req.Header.Set("User-Agent", utils.UA)
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
for _, cookie := range resp.Cookies() {
|
|
if cookie.Name == "SESSDATA" {
|
|
return cookie, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("no SESSDATA cookie")
|
|
}
|
|
|
|
type CaptchaResp struct {
|
|
Token string `json:"token"`
|
|
Gt string `json:"gt"`
|
|
Challenge string `json:"challenge"`
|
|
}
|
|
|
|
func NewCaptcha(ctx context.Context) (*CaptchaResp, error) {
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://passport.bilibili.com/x/passport-login/captcha", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Referer", "https://passport.bilibili.com/login")
|
|
req.Header.Set("User-Agent", utils.UA)
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var captcha captcha
|
|
err = json.NewDecoder(resp.Body).Decode(&captcha)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &CaptchaResp{
|
|
Token: captcha.Data.Token,
|
|
Gt: captcha.Data.Geetest.Gt,
|
|
Challenge: captcha.Data.Geetest.Challenge,
|
|
}, nil
|
|
}
|
|
|
|
type captcha struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
TTL int `json:"ttl"`
|
|
Data struct {
|
|
Type string `json:"type"`
|
|
Token string `json:"token"`
|
|
Geetest struct {
|
|
Challenge string `json:"challenge"`
|
|
Gt string `json:"gt"`
|
|
} `json:"geetest"`
|
|
Tencent struct {
|
|
Appid string `json:"appid"`
|
|
} `json:"tencent"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type sms struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Data struct {
|
|
CaptchaKey string `json:"captcha_key"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
func NewSMS(ctx context.Context, tel, token, challenge, validate string) (captchaKey string, err error) {
|
|
b, err := getBuvidCookies()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
data := url.Values{}
|
|
data.Set("cid", "86")
|
|
data.Set("tel", tel)
|
|
data.Set("source", "main-fe-header")
|
|
data.Set("token", token)
|
|
data.Set("challenge", challenge)
|
|
data.Set("validate", validate)
|
|
data.Set("seccode", fmt.Sprintf("%s|jordan", validate))
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://passport.bilibili.com/x/passport-login/web/sms/send", strings.NewReader(data.Encode()))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
req.Header.Set("Referer", "https://passport.bilibili.com/login")
|
|
req.Header.Set("User-Agent", utils.UA)
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
for _, c := range b {
|
|
req.AddCookie(c)
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var sms sms
|
|
err = json.NewDecoder(resp.Body).Decode(&sms)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return sms.Data.CaptchaKey, nil
|
|
}
|
|
|
|
func LoginWithSMS(ctx context.Context, tel, code, captchaKey string) (*http.Cookie, error) {
|
|
data := url.Values{}
|
|
data.Set("cid", "86")
|
|
data.Set("tel", tel)
|
|
data.Set("code", code)
|
|
data.Set("source", "main-fe-header")
|
|
data.Set("captcha_key", captchaKey)
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://passport.bilibili.com/x/passport-login/web/login/sms", strings.NewReader(data.Encode()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Referer", "https://passport.bilibili.com/login")
|
|
req.Header.Set("User-Agent", utils.UA)
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, cookie := range resp.Cookies() {
|
|
if cookie.Name == "SESSDATA" {
|
|
return cookie, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("no SESSDATA cookie")
|
|
}
|