新浪微博模拟登陆过程:
过程说明:
1.登陆 weibo.com ,这一步的主要目的是获取新浪微博的一个名字为ssologin.js的 js 脚本文件,在weibo.com的页面中连接为 http://js.t.sinajs.cn/t35/miniblog/static/js/sso.js?version=8818b2c42b785af9 。
该脚本文件中包含了整个登陆过程,同时包含了 RSA加密算法,WSSE加密算法和BASE64加密算法。目前该脚本文件的版本为 1.4.2 ,版本一直在升级,升级过程加密算法可能会做更改。
2.请求servertime,pubkey等数据,通过GET 请求获取一个 JSON格式的数据。URL为
该url请求的过程在上面的js脚本里面也有描述。
js脚本内容为:
url=makeURL(url,{"entry":me.entry,"callback":me.name+".preloginCallBack","su":username,"rsakt":"mod"});
Entry 值为 sso ,
callback 值为 sina ,
su 为用户名 该用户名经过 base64 加密,js脚本内加密方法为
username = sinaSSOEncoder.base64.encode(urlencode(username));
Urlencode方法填充了 username ,是js自带的方法
base64即为 base64加密算法
请求完成后会得到一组JSON格式的数据,如:
sinaSSOController.preloginCallBack({"retcode":0,"servertime":1355568671,"pcid":"yf-4b6594300cb4bdf729f0f1ec913b4cdaf7bb","nonce":"8OPVH7","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","exectime":0})
Retcode 0 代表执行成功
Pcid 暂时用不到
Servertime和nonce 很重要,这两个数据很重要,是配合对账户密码进行加密的值
Pubkey 是加密算法的公钥
Rsakv 代表rsa加密算法
上述数据中,servertime,nonce,rsakv是需要传回服务器的数据
3.提交的表单格式如下:
name | value | 说明 |
entry | 固定值 | |
gateway | 1 | 固定值 |
from | 空值 | |
savestate | 7 | 固定值 |
useticket | 1 | 固定值 |
vsnf | 1 | 固定值 |
ssosimplelogin | 1 | 固定值 |
su | bG9sZWVfayU0MDE2My5jb20= | 该字段是账户经过base64加密后的值(测试值为 lolee_k@163.com) |
service | miniblog | 固定值 |
servertime | 1355554959 | 上一步获取的值 |
nonce | 9BN6RU | 上一步获取的值 |
pwencode | rsa2/wsse | 目前新浪使用的是rsa2,但是网上之前的值为wsse,与所使用的加密算法有关系 |
rsakv | 1330428213 | 上一步获取的值 |
sp | 一个256位的密文 | |
encoding | UTF-8 | 固定值 |
prelt | 685 | 一个随机时间,最小值为100 在100-1000内取随机值 |
url | http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack | 固定值 |
returntype | META | 固定值 |
该表单提交到 URL:
http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.2) 此处显示了ssologin.js 的版本,后期可能会一直变化
关于 sp 字段的说明:
对于sp的计算新浪给出了两种算法,代码如下
RSA:
request["servertime"] = me.servertime;
request["nonce"] = me.nonce;
request["pwencode"] = "rsa2";
equest["rsakv"] = me.rsakv;
var RSAKey = new sinaSSOEncoder.RSAKey();
RSAKey.setPublic(me.rsaPubkey, '10001');
password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password);
WSSE:
request["servertime"] = me.servertime;
request["nonce"] = me.nonce;
request["pwencode"] = "wsse";
password=sinaSSOEncoder.hex_sha1(""sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce);
RSA中将 servertime,nonce与账户密码连接然后加密
WSSE中经过了三次SHA1 加密,且其中加入了 servertime 和 nonce 的值来干扰。即: 两次SHA1加密后, 将结果加上 servertime 和 nonce 的值, 再SHA1 算一次。
我对于sp的处理是直接将 ssologin.js 脚本中的RSA加密算法部分抽取到一个新建的js脚本中,然后通过java进行调用,不过抽取的js代码需要做一些变化。
4.表单提交之后会得到一个html文件,文件内容如下:
<html>
<head>
<title>新浪通行证</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" /><script charset="utf-8" src="http://i.sso.sina.com.cn/js/ssologin.js"></script></head><body>正在登录 ...<script>
try{sinaSSOController.setCrossDomainUrlList({"retcode":0,"arrURL":["http:\/\/kandian.com\/logon\/do_crossdomain.php?action=login&savestate=1356349064"]});}
catch(e){}try
{sinaSSOController.crossDomainAction('login',function(){
location.replace('http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&ssosavestate=1356349064&ticket=ST-MjEwNzMzNjY1NQ==-1355744264-tc-1CF21DFAC3ACCD433BA1687E5DAAE033&retcode=0');});}
catch(e){}</script></body></html>
红色部分为下一步请求的 url ,接着 GET请求红色字段的url,得到结果如下:
<html><head>
<script language='javascript'>parent.sinaSSOController.feedBackUrlCallBack(
{"result":true,"userinfo":{"uniqueid":"2107336655","userid":"lolee_k@163.com","displayname":"lolee_k","userdomain":"?wvr=5&lf=reg"}});
</script></head><body></body></html>
这个地方获得的cookie比较多,有什么UOV,SUP等等很多。我们需要将这些cookies都保存好。
5.上一步得到的网页中包含下面json数据
{"uniqueid":"2107336655","userid":"lolee_k@163.com","displayname":"lolee_k","userdomain":"?wvr=5&lf=reg"}}
现在就可以登陆主页了,这一步要注意的是必须将之前的Cookie全部传回去,获取个人主页的URL为 weibo.com/u/2107336655?wvr=5&lf=reg。即json数据中的值。
最后附上自己写的模拟登陆的代码和操作js脚本文件的java代码,其中代码中使用了httpclient4.0和jackson依赖。
对于js脚本,java中自带了脚本引擎,调用过程很简单。到目前为止,使用该方法仍然可以登录新浪微博。