Webtop 既然是用html+css+js来开发桌面APP,那么在做一些娱乐社交应用的时候,去整合一些开放平台的时候也是十分方便的。我们直接可以使用jQuery的ajax来和开放平台交互就可以。
昨天,我在尝试整合人人网的开放平台的时候。遇到了一些小的问题,这里给大家介绍一个解决的方案。
人人网的API提供了两种登录方式:一种是web服务端的应用,另外一种是客户端应用。但是Webtop又不是一个真正的本地应用(这里这样说的原因是目前webtop的api还是很少,不能和原生的c++,java等相比),所以在处理登录的时候。我们只能采用比较特殊的方法。
我们在Webtop的界面上面用iframe来嵌套人人网的应用授权页面,来让用户完成登录授权。Webtop肯定不是一个Web服务端的应用,所以我们这里采用客户端的登录方式。
$('#app_content').append('<iframe id="rriframe" width="100%" height="400" src="https://graph.renren.com/oauth/authorize?client_id=000000&redirect_uri=http://graph.renren.com/oauth/login_success.html&response_type=token" onload="Rest.rr.loginBack()"></iframe>');
人人网的 OAuth授权页面的地址为 https://graph.renren.com/oauth/authorize ,我们需要给它传3个参数:client_id、redirect_uri、response_type。 client_id 的值是你的应用注册的id,redirect_uri是用户登陆后你的回调页面,response_type是指定不同的登录方式,客户端登录的话选择 token 。
在用户登陆以后,人人网会重定向到你的CallBack页面,并传给你access_token以及expires_in。access_token这个值我们是要保存下来的,后面请求用户其他数据的时候是需要把这个值传会给人人网的。
但是在Webtop我们的当前页面的地址是一个本地文件的地址 file :/// 开头,人人网会对你的CallBack URL 验证的,我们的 window.location 的值并不合法,所以我们当前页面的地址是没法作为回调页面传给人人网的。
这个回调页面的问题纠结了我好久,既然Webtop本身是不能提供一个合法的页面作为回调地址传给人人网。我们只能通过用人人网的测试页面,然后来拦截这个iframe的src的变化,截取这个access_token。
上面的iframe代码中,我们加了一个 onload事件,每次iframe加载页面的时候就会触发这个方法。当然在用户登录成功以后也会触发。登录后,回调的地址如下格式:
http://YOUR_CALLBACK_URL#access_token=1000%7C5.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-222209506&expires_in=64090
我们对这个地址进行截取,去除access_token的值:
var frame = document.getElementById("rriframe"); var url = frame.contentWindow.location.href; Log.info(url); var _s = url.split('#'); var _ss = _s[1].split('&'); var token = _ss[0].split('=')[1]; RR.token = token.replace('%7C', '|');
这里的地址是UTF8编码的,所以要将 %7C 替换成 | 。这个要注意,耽误了我很久。
基于OAuth的开发平台的每次请求,都会要求签名认证。人人API 服务器使用了签名机制(即sig参数)来认证应用。签名是由请求参数和应用的私钥Secret Key经过MD5加密后生成的字符串。应用在调用人人API之前,要计算出签名,并追加到请求参数中。
人人网提供了一个计算sig的 js demo。这个地址我一时又找不到了,人人网的开发平台上面有。它里面有一个md5.js 文件,我们就用它提供的方法来计算sig的值。
var params = []; params.push('api_key='+RR.api_key); params.push('method=users.getInfo'); var callid = new Date().valueOf(); params.push('call_id=' + callid); params.push('v=1.0'); params.push('format=json'); params.push('access_token=' + RR.token); Log.info(params); var sig = Rest.rr.generateSigFromArray(params, RR.secret_key);
generateSigFromArray : function(a, secret_key) { //数组a按字典序排序 a.sort(function(a, b) { //取得各参数名 a_k = (a.split("="))[0]; b_k = (b.split("="))[0]; return (a_k < b_k) ? -1 : 1; }) //按序连接所有key=value与secret_key var str = a.join('') + secret_key; //计算md5 return hex_md5(str); }
这里 RR.api_key 是你注册人人网应用是分配给你的key,RR.secret_key是应用的secret key。RR.token的值是刚才我们截取的access_token 的值。
这里传给md5计算的字符串的顺序貌似是固定的,这里要注意一下。每次请求的参数都要参与sig的计算哦!
计算出sig的值,我们就可以请求用户的信息。这里请求的参数必须都参与sig值的计算,然后再加上sig的值,一起post给人人网开发平台。他的请求地址为:http://api.renren.com/restserver.do 。都使用POST方式。
$.ajax({ url : RR.rrq, type : "post", data : { 'method' : 'users.getInfo', 'v' : '1.0', 'format' : 'json', 'call_id' : callid, 'access_token' : RR.token, 'sig' : sig, 'api_key' : RR.api_key }, success : function(data) { RR.user = JSON.parse(data)[0]; Log.info(RR.user); Rest.rr.showRenRen(); } });
我们这里选择了 format的方式为json,所以会接受到json格式的数据。同时也支持xml。