Last active
June 1, 2022 16:46
-
-
Save reitowo/db12f5ba66c37cfe10bb8912f82de3f0 to your computer and use it in GitHub Desktop.
Weibo Persistent Cookie
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 储存Cookie类 | |
public class WeiboToken { | |
public string Gsid { get; set; } | |
public string Uid { get; set; } | |
public DateTime LoginTime { get; set; } | |
public List<Cookie> Cookies { get; set; } | |
} | |
// Step 1: Login | |
if (msg.Content.StartsWith("weibo")) { | |
try { | |
var phone = "<Your Phone Number>"; | |
if (msg.Content != "weibo") { | |
phone = msg.Content.Split(' ')[1].Trim(); | |
} | |
using var http = new HttpClient(new HttpClientHandler { | |
AutomaticDecompression = DecompressionMethods.All | |
}); | |
var resp = await http.PostAsync($"https://api.weibo.cn/2/account/login_sendcode", | |
new FormUrlEncodedContent(new Dictionary<string, string>() { | |
{"phone", phone} | |
})); | |
var text = await resp.Content.ReadAsStringAsync(); | |
var json = JObject.Parse(text); | |
var sendsms = json["sendsms"].Value<bool>(); | |
if (sendsms) { | |
var m = await z.api.GetDirectMessageApi() | |
.SendTextMessageAsync(msg.GuildId, "已发送验证码", msg.Id); | |
_weiboSmsMessageId = m.Id; | |
_weiboPhone = phone; | |
} else { | |
Logger.LogError(text); | |
await z.api.GetDirectMessageApi() | |
.SendTextMessageAsync(msg.GuildId, "验证码发送失败", msg.Id); | |
} | |
} catch (Exception ex) { | |
Logger.LogError(ex, "登陆错误"); | |
await z.api.GetDirectMessageApi().SendTextMessageAsync(msg.GuildId, "登录出错", msg.Id); | |
} | |
return true; | |
} | |
// Step 2: Verify Code | |
if (msg.MessageReference != null && msg.MessageReference.MessageId == _weiboSmsMessageId) { | |
try { | |
var code = msg.Content; | |
using var http = new HttpClient(new HttpClientHandler { | |
AutomaticDecompression = DecompressionMethods.All | |
}); | |
var resp = await http.PostAsync($"https://api.weibo.cn/2/account/login", | |
new FormUrlEncodedContent(new Dictionary<string, string>() { | |
{"phone", _weiboPhone}, | |
{"smscode", code}, | |
{"getuser", "0"}, | |
{"getcookie", "1"}, | |
{"getoauth", "1"} | |
})); | |
var text = await resp.Content.ReadAsStringAsync(); | |
var json = JObject.Parse(text); | |
var status = json["status"].Value<int>(); | |
if (status == 1) { | |
var webCookie = json["cookie"]["cookie"][".weibo.cn"].Value<string>(); | |
string GetCookie(string val) { | |
return webCookie![ | |
(webCookie.IndexOf($"{val}=", StringComparison.Ordinal) + val.Length + 1)..webCookie | |
.IndexOf(";", | |
webCookie.IndexOf($"{val}=", StringComparison.Ordinal), | |
StringComparison.Ordinal)]; | |
} | |
var sub = GetCookie("SUB"); | |
var subp = GetCookie("SUBP"); | |
var token = new WeiboToken() { | |
Gsid = json["gsid"].Value<string>(), | |
Uid = json["uid"].Value<string>(), | |
LoginTime = DateTime.Now, | |
Cookies = new List<Cookie>() { | |
new Cookie() { | |
Name = "SUB", | |
Value = sub, | |
Domain = ".weibo.cn", | |
Path = "/", | |
Secure = true, | |
HttpOnly = true | |
}, | |
new Cookie() { | |
Name = "SUBP", | |
Value = subp, | |
Domain = ".weibo.cn", | |
Path = "/", | |
Secure = true | |
} | |
} | |
}; | |
await db.SaveSingleton(token); | |
GetModule<WeiboModule>().ScheduleReloadToken(); | |
await z.api.GetDirectMessageApi() | |
.SendTextMessageAsync(msg.GuildId, "登录成功", msg.Id); | |
} else { | |
Logger.LogError(text); | |
await z.api.GetDirectMessageApi() | |
.SendTextMessageAsync(msg.GuildId, "登录失败", msg.Id); | |
} | |
} catch (Exception ex) { | |
Logger.LogError(ex, "登陆错误"); | |
await z.api.GetDirectMessageApi().SendTextMessageAsync(msg.GuildId, "登录出错", msg.Id); | |
} | |
return true; | |
} | |
// Step 3: 从抓包拿s参数 | |
// 下面链接疑似有s参数生成算法,但没试过 | |
// https://github.com/corberan/Security-Research/blob/8ce59b382a0bde927b1efc1075bda08acf739f47/wbcall.go | |
private static Dictionary<string, string> _sTable = new() { | |
{"<Your Weibo UID>", "<This UID's s param>"}, | |
}; | |
// Step 4: 获取最新微博 | |
private async Task ReloadToken() { | |
await using var db = new TBotDb(); | |
_token = await db.GetSingleton<WeiboToken>(); | |
if (_token != null) { | |
_client?.Dispose(); | |
_client = new HttpClient(); | |
_client.DefaultRequestHeaders.Add("Authorization", $"WB-SUT {_token.Gsid}"); | |
Logger.LogInformation($"重载微博 {JsonConvert.SerializeObject(_token)}"); | |
} | |
} | |
private Dictionary<string, string> GetCommonQueryParams() { | |
return new Dictionary<string, string> { | |
{"gsid", _token.Gsid}, | |
{"networktype", "wifi"}, | |
{"c", "android"}, | |
{"s", _sTable[_token.Uid]}, // s参数 | |
{"from", "10C4095010"}, | |
{"lang", "zh_CN"}, | |
}; | |
} | |
private async Task QueryWeibo(CancellationToken cancellationToken) { | |
Logger.LogTrace($"查询微博"); | |
var payload = GetCommonQueryParams(); | |
payload.Add("image_type", "heif"); | |
var resp = await _client.GetStringAsync("https://api.weibo.cn/2/statuses/friends/timeline?" + | |
string.Join("&", payload.Select(x => $"{x.Key}={x.Value}")), | |
cancellationToken); | |
//...... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment