Skip to content

Instantly share code, notes, and snippets.

@reitowo
Last active June 1, 2022 16:46
Show Gist options
  • Save reitowo/db12f5ba66c37cfe10bb8912f82de3f0 to your computer and use it in GitHub Desktop.
Save reitowo/db12f5ba66c37cfe10bb8912f82de3f0 to your computer and use it in GitHub Desktop.
Weibo Persistent Cookie
// 储存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