写WINFORM登录QQ邮箱时遇到一个问题,QQ邮箱返回的Set-Cookie值里有","会导致Cookie不完整,虽然登录成功却无法正常访问.
因为我的代码有很多自己的类库,所以不方便上传源码,为了方面大家帮助我,我尽可能的把问题描述清楚.
首先GET请求http://w.mail.qq.com/cgi-bin/loginpage?f=xhtml分析出QQ邮箱分配给当前用户的域名(登录地址)
然后POST请求http://w21.mail.qq.com/cgi-bin/login(这是上面分析出来的,w21是QQ邮箱随机分配的),POST数据包(device=&f=xhtml&tfcont=&uin=QQ号码&aliastype=@qq.com&pwd=QQ密码明文&btlogin=+%E7%99%BB%E5%BD%95+)
登录成功的特征是"正在登录",这个时候分析出真实的登录地址http://w21.mail.qq.com/cgi-bin/today?sid=EHb6FRgYZzEOWVIdUfzT5vNw,4,zv5AxMDwb&first=1
GET请求真实登录地址,如果COOKIE正确则回进入邮箱首页,如果不正确则提示登录超时.
问题出在POST请求http://w21.mail.qq.com/cgi-bin/login后返回的Set-Cookie值里有",",HttpWebResponse自动处理后Cookie会丢失,导致GET真实登录地址就超时了.
POST请求返回的Set-Cookie
将HttpWebResponse.Cookies设置给HttpWebRequest.CookieContainer后提交请求Cookie丢失成这样
分析出问题所在查阅了很多相关问题,尝试把HttpWebResponse.Cookies取回来自己处理后再设置给HttpWebRequest.CookieContainer但是因为逗号原因会抛"Cookie Value 部分不正确"异常
于是尝试将","替换为"%2C"
MSDN推荐的方法将Cookie.Value加上引号"\"123,456\""在设置
虽然这2个方法都确保了Cookie的完整性,但是QQ邮箱服务器并不能解析%2C 和带双引号的值得所以Cookie仍然是不正确的.
为了验证是Cookie问题导致超时,我用其他语言(Cookie不处理",")尝试,可以正确登录,而GET请求真实登录地址的Cookie是这样的
最后的问题是如何让HttpWebRequest.CookieContainer兼容"," 如果只能使用%2C或双引号解决","问题 又如何让QQ邮箱服务器正确识别Cookie.
我的建议是(没有写过代码),既然Cookie不好用,那么直接使用Headers(是一个WebHeaderCollection) 好了,直接从HttpWebResponse中提取键值为"Set-Cookie"的头部,添加到HttpWebRequest的键值为"Cookie"的头部中去,怎么样? (Cookie 不在那个所谓的受限制的标头中)此路不通,另走他路吧。
这个方法我代码实现了一下,走不通~QQ不会认!
我是通过组合cookie ,然后放入头部
request.CookieContainer = cc;
if (!string.IsNullOrWhiteSpace(header.cookie))
request.Headers.Set("Cookie", header.cookie);
如果CookieContainer不给赋值的话,QQ就不验证了,说是没有开启QQ。所以我传了两个过去
但是结果还是没有得到结果。
返回超时 session_timeout
MSDN上说逗号是保留字符:"The Value of a Cookie must not be Nothing. The following characters are reserved and cannot be used for this property: semicolon, comma."
所以,没有办法让HttpWebRequest.CookieContainer兼容逗号,只能使用%2C或双引号解决","。
如何让QQ邮箱服务器正确识别Cookie?
我想到的一个办法(未经过实际验证):
通过代理服务器访问QQ邮箱,前提是代理服务器能识别%2C,并且会将%2C转换为逗号。
把代码放上来,我帮你调试看看情况。
看有没有下划线,要转换的。
用Socket试试怎样?
这个问题最终的解决方案是我自己用通过COM封装WinHttp.dll不在使用.net的HttpWebRequest和HttpWebResponse
楼主,您太NB了~~我也遇到和你一模一样的问题~~~!!!
你解决了,我还没有解决。如果不放在 CookieContainer ,然后QQ会抛给你cookie没有开启来了。
我用 request.Headers.Set("Cookie", header.cookie);
然后就报
{title : \"cgi exception\",appname : \"getwpkey\",errcode: \"-2\",errmsg: \" \\x3cscript\\x3egetTop().location.href=\\x22/cgi-bin/loginpage?s=session_timeout\\x26from=\\x26r=607a42e4a7c6f1d6852cb2a2cccf1645\\x22;\\x3c/script\\x3e\" }"
我是取 http://mail.qq.com/cgi-bin/getwpkey?r=0.305186006706208&resp_charset=UTF8&ef=js&sid=ULk3O_hP4B9zLSx9
这个页面。如果正常的话,应该是返回 ({k:"8K_ZrVYP6dP-AV-f",t:0})
请楼主分享一下您写的 封装好不好,我调试了好几天,都没有进展。QQ邮箱:33543145@qq.com
mark