mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-09-06 16:07:26 +08:00
fix: 修复刷新凭据相关的异常
This commit is contained in:
+14
-3
@@ -1,6 +1,7 @@
|
|||||||
use reqwest::{header, Method};
|
use reqwest::{header, Method};
|
||||||
|
|
||||||
use crate::bilibili::Credential;
|
use crate::bilibili::Credential;
|
||||||
|
use crate::config::CONFIG;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
// 一个对 reqwest::Client 的简单封装,用于 Bilibili 请求
|
// 一个对 reqwest::Client 的简单封装,用于 Bilibili 请求
|
||||||
@@ -20,7 +21,13 @@ impl Client {
|
|||||||
header::REFERER,
|
header::REFERER,
|
||||||
header::HeaderValue::from_static("https://www.bilibili.com"),
|
header::HeaderValue::from_static("https://www.bilibili.com"),
|
||||||
);
|
);
|
||||||
Self(reqwest::Client::builder().default_headers(headers).build().unwrap())
|
Self(
|
||||||
|
reqwest::Client::builder()
|
||||||
|
.default_headers(headers)
|
||||||
|
.gzip(true)
|
||||||
|
.build()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// a wrapper of reqwest::Client::request to add credential to the request
|
// a wrapper of reqwest::Client::request to add credential to the request
|
||||||
@@ -65,9 +72,13 @@ impl BiliClient {
|
|||||||
let Some(credential) = self.credential.as_mut() else {
|
let Some(credential) = self.credential.as_mut() else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
if credential.check(&self.client).await? {
|
if !credential.need_refresh(&self.client).await? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
credential.refresh(&self.client).await
|
credential.refresh(&self.client).await?;
|
||||||
|
|
||||||
|
let mut config = CONFIG.lock().unwrap();
|
||||||
|
config.credential = Some(credential.clone());
|
||||||
|
config.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-18
@@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
|
||||||
|
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -7,11 +6,12 @@ use reqwest::{header, Method};
|
|||||||
use rsa::pkcs8::DecodePublicKey;
|
use rsa::pkcs8::DecodePublicKey;
|
||||||
use rsa::sha2::Sha256;
|
use rsa::sha2::Sha256;
|
||||||
use rsa::{Oaep, RsaPublicKey};
|
use rsa::{Oaep, RsaPublicKey};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::bilibili::Client;
|
use crate::bilibili::Client;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Credential {
|
pub struct Credential {
|
||||||
pub sessdata: String,
|
pub sessdata: String,
|
||||||
pub bili_jct: String,
|
pub bili_jct: String,
|
||||||
@@ -32,7 +32,7 @@ impl Credential {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 检查凭据是否有效
|
/// 检查凭据是否有效
|
||||||
pub async fn check(&self, client: &Client) -> Result<bool> {
|
pub async fn need_refresh(&self, client: &Client) -> Result<bool> {
|
||||||
let res = client
|
let res = client
|
||||||
.request(
|
.request(
|
||||||
Method::GET,
|
Method::GET,
|
||||||
@@ -43,7 +43,7 @@ impl Credential {
|
|||||||
.await?
|
.await?
|
||||||
.json::<serde_json::Value>()
|
.json::<serde_json::Value>()
|
||||||
.await?;
|
.await?;
|
||||||
res["refresh"].as_bool().ok_or("check refresh failed".into())
|
res["data"]["refresh"].as_bool().ok_or("check refresh failed".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
|
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
|
||||||
@@ -59,14 +59,14 @@ impl Credential {
|
|||||||
// 调用频率很低,让 key 在函数内部构造影响不大
|
// 调用频率很低,让 key 在函数内部构造影响不大
|
||||||
let key = RsaPublicKey::from_public_key_pem(
|
let key = RsaPublicKey::from_public_key_pem(
|
||||||
"-----BEGIN PUBLIC KEY-----
|
"-----BEGIN PUBLIC KEY-----
|
||||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLgd2OAkcGVtoE3ThUREbio0Eg
|
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLgd2OAkcGVtoE3ThUREbio0Eg
|
||||||
Uc/prcajMKXvkCKFCWhJYJcLkcM2DKKcSeFpD/j6Boy538YXnR6VhcuUJOhH2x71
|
Uc/prcajMKXvkCKFCWhJYJcLkcM2DKKcSeFpD/j6Boy538YXnR6VhcuUJOhH2x71
|
||||||
nzPjfdTcqMz7djHum0qSZA0AyCBDABUqCrfNgCiJ00Ra7GmRj+YCK1NJEuewlb40
|
nzPjfdTcqMz7djHum0qSZA0AyCBDABUqCrfNgCiJ00Ra7GmRj+YCK1NJEuewlb40
|
||||||
JNrRuoEUXpabUzGB8QIDAQAB
|
JNrRuoEUXpabUzGB8QIDAQAB
|
||||||
-----END PUBLIC KEY-----",
|
-----END PUBLIC KEY-----",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
|
let ts = chrono::Local::now().timestamp_millis();
|
||||||
let data = format!("refresh_{}", ts).into_bytes();
|
let data = format!("refresh_{}", ts).into_bytes();
|
||||||
let mut rng = rand::rngs::OsRng;
|
let mut rng = rand::rngs::OsRng;
|
||||||
let encrypted = key.encrypt(&mut rng, Oaep::new::<Sha256>(), &data).unwrap();
|
let encrypted = key.encrypt(&mut rng, Oaep::new::<Sha256>(), &data).unwrap();
|
||||||
@@ -109,19 +109,17 @@ impl Credential {
|
|||||||
])
|
])
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
let set_cookie = res
|
let set_cookies = res.headers().get_all(header::SET_COOKIE);
|
||||||
.headers()
|
|
||||||
.get(header::SET_COOKIE)
|
|
||||||
.ok_or("no set_cookie header")?
|
|
||||||
.to_str()?;
|
|
||||||
let mut credential = Credential {
|
let mut credential = Credential {
|
||||||
buvid3: self.buvid3.clone(),
|
buvid3: self.buvid3.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
|
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
|
||||||
let cookies: Vec<Cookie> = Cookie::split_parse_encoded(set_cookie)
|
let cookies: Vec<Cookie> = set_cookies
|
||||||
.filter(|x| x.as_ref().is_ok_and(|x| required_cookies.contains(x.name())))
|
.iter()
|
||||||
.map(|x| x.unwrap())
|
.filter_map(|x| x.to_str().ok())
|
||||||
|
.filter_map(|x| Cookie::parse(x).ok())
|
||||||
|
.filter(|x| required_cookies.contains(x.name()))
|
||||||
.collect();
|
.collect();
|
||||||
if cookies.len() != required_cookies.len() {
|
if cookies.len() != required_cookies.len() {
|
||||||
return Err("not all required cookies found".into());
|
return Err("not all required cookies found".into());
|
||||||
|
|||||||
Reference in New Issue
Block a user