Q邮箱登陆采用https 安全通道,测试的时候使用http会导致验证码不正确或者输入多个验证码才能返回成功(IP没有异常的情况下)
@qq.com 域的用户基本全部需要输入验证码,@vip.qq.com可根据情况去判断是否需要验证码
验证码获取地址:https://mail.qq.com/cgi-bin/getverifyimage?aid=23000101&f=html&ck=1&"+Utils.getRadomNum()
Utils.getRadomNum() 方法生成16位随机小数
登陆提交地址:https://mail.qq.com/cgi-bin/login?sid=,2,zh_CN
提交内容:sid=%2C2%2Czh_CN&firstlogin=false&starttime={0}&redirecturl=&f=html&p={1}&ept=0&delegate_url=&s=&ts={2}&from=&ppp=&chg=0&target=&checkisWebLogin=6&uin={3}&aliastype=%40qq.com&pp=00000000000&verifycode={4}
其中{0}是一个时间戳,填写当前距1970-1-1 的毫秒数,js里边的 new date().getTime() 或者 (new date()).valueOf()
{1}为密码
{2}也是一个时间戳,是服务器给返回的,可以在登陆页面的隐藏域中找到,经测试是 当然时间的unix时间(unix时间戳)
{3}是QQ号码
{4}为验证码
提交方式:post
如果没有登陆成功 js会控制转向,其中源码包含errtype=1 为密码或者帐号错误 errtype=2为验证码错误
登陆成功服务器会给分配类似(m123.mail.qq.com)的邮件服务器,会给写入大量cookie ,在这个返回页面中可以获取到sid
编码过程中出现的问题:以http方式去登陆会出现验证码错误,但是以https的方式 服务器却不给返回分配的邮件服务器,但是会给写登陆成功的cookie,好在在cookie里也可以取到邮件服务器,这个问题也就不是问题了
还有一个步骤,在发邮件的时候 需要一个key,这个key的值为cookie里的qm_sid ,这个key随便写好像也能成功,如果获取的话需要在登陆成功页面提取一个连接去访问,然后去取隐藏域,这个请参见下边的代码
[C#] 纯文本查看 复制代码 public System.IO.Stream GetVerifyCodePic()
{
//HttpHelper.GetHtml("https://mail.qq.com/cgi-bin/loginpage", User.Cookie);
return HttpHelper.GetStream("https://mail.qq.com/cgi-bin/getverifyimage?aid=23000101&f=html&ck=1&"+Utils.getRadomNum(), User.Cookie);
}
登陆代码
[C#] 纯文本查看 复制代码 public void Login()
{
//string content = HttpHelper.GetHtml("https://mail.qq.com/cgi-bin/loginpage", User.Cookie);
//string ts = Utils.getStringByRegex(content, "(input type=\"hidden\" name=\"ts\" value=\")(?<ts>.+?)(\" )", "ts", 0);
string url = "https://mail.qq.com/cgi-bin/login?sid=,2,zh_CN";
string postData = string.Format("sid=%2C2%2Czh_CN&firstlogin=false&starttime={0}&redirecturl=&f=html&p={1}&ept=0&delegate_url=&s=&ts={2}&from=&ppp=&chg=0&target=&checkisWebLogin=6&uin={3}&aliastype=%40qq.com&pp=00000000000&verifycode={4}", Utils.GetTime(), User.Password, Utils.UNIX_TIMESTAMP(), User.UserName, User.VerifyCode);
string result = HttpHelper.GetHtml(url, postData, true, User.Cookie);
if(result.Contains("errtype=2"))
{
User.Status = UserStatus.VerifyCodeError;
}else if(result.Contains("errtype=1"))
{
User.Status = UserStatus.PasswordError;
}else
{
result = result.Replace("+", "@");
//User.Host = Utils.getStringByRegex(result, "(var urlHead=\")(?<url>.+?)(\";)", "url", 0);
User.Host = "http://" + Utils.GetGtkByCookieSkey("edition", User.Cookie) + "/cgi-bin/";
string targetUrl = "";
string target = "";
string mailto = "";
string frame = Utils.getStringByRegex(result, "(targetUrl = urlHead @ \")(?<sid>.+?)(\";)", "sid", 0);
targetUrl = User.Host + frame;
if (frame != "")
{
User.Sid = frame.Substring(15);
}
if (targetUrl == "")
{
targetUrl = "" != "" ? "" : "/cgi-bin/loginpage";
}
if (targetUrl.IndexOf("?") != -1)
{
targetUrl += "&r=" + Utils.getStringByRegex(result, "(targetUrl@=\"&r=)(?<r>.+?)(\";)", "r", 0);
}
string res = HttpHelper.GetHtml(targetUrl, User.Cookie);
if (User.Host != "" && User.Sid != "")
{
User.Status = UserStatus.Logined;
string s2 = HttpHelper.GetHtml(User.Host + "grouplist?sid=" + User.Sid + "&t=compose_group&gid=&s=from_mail_list", User.Cookie);
User.Key = Utils.getStringByRegex(s2, "(<input type=\"hidden\" name=\"sid\" value=\"?.+?\" /><input id=\")(?<key>.+?)(\" type=\"hidden\")", "key", 1);
}
else
{
User.Status = UserStatus.LoginError;
}
}
}
StarTime代码
[C#] 纯文本查看 复制代码 public static long GetTime()
{
//DateTime dateTime = DateTime.Now;
//DateTime startDate = new DateTime(1970, 1, 1);
//DateTime endDate = DateTime.Now;
//TimeSpan span = endDate - startDate;
//return (long)(span.TotalMilliseconds);
DateTime dt = DateTime.Now;
long dtTicks = dt.ToUniversalTime().Ticks;
long jsBeginTick = DateTime.Parse("1970-1-1").Ticks;
long dtJsTicks = (dtTicks - jsBeginTick) / (1000 * 10);
return dtJsTicks;
}
[C#] 纯文本查看 复制代码 public static long UNIX_TIMESTAMP()
{
return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
|