京东SSO单点登陆实现分析(转)
京东的sso流程:
初始访问状态:
cookies:
![](http://images0.cnblogs.com/blog/129849/201305/17083358-424b3261aa554ca7907bb606fde000c3.png)
http请求:
![](http://images0.cnblogs.com/blog/129849/201305/17083433-5d87010a992944aca50e53eede9f8775.png)
1.在首页点击登陆,跳转至passport.360buy.com,给予验证cookie alc(可以试试在提交登陆信息前删除该cookie)
cookies
![](http://images0.cnblogs.com/blog/129849/201305/17083506-22b63b35e3ed4052946c49a5296c4066.png)
http请求
![](http://images0.cnblogs.com/blog/129849/201305/17083528-7843110b6cce49dfb66eada64bd15930.png)
2.填写用户名密码,提交登陆,验证alc,登陆成功则给予sso的cookie ceshi3.com,跳转至首页
cookies:
![](http://images0.cnblogs.com/blog/129849/201305/17083547-6c4214bb88c843069d9367eb2134fd32.png)
3.首页异步ajax,向passport.360buy.com发起hello请求,hello请求返回json对象a,a包含sso(url地址数组,含请求参数)
http请求:
![](http://images0.cnblogs.com/blog/129849/201305/17083602-79aa74f5ec244c389c605cd43c2e3405.png)
发起hello请求的脚本如下:
点击(此处)折叠或打开
- <script type="text/javascript">
- (function ($) {
- $("#shortcut .menu").Jdropdown({ delay: 50 });
- var helloUrl = window.location.protocol + "//passport.360buy.com/new/helloService.ashx?m=ls";
- jQuery.ajax({ url: helloUrl,
- dataType: "jsonp",
- scriptCharset: "gb2312",
- success: function (a) {
- //if (a && a.info) { $("#loginbar").html(a.info); }
- if (a && a.sso) {
- $.each(a.sso, function () { $.getJSON(this) })
- }
- }
- });
- }
- )(jQuery);</script>
【以上这段是在登出页发现的,京东首页实际使用的是压缩过的,来自http://misc.360buyimg.com/lib/js/2012/lib-v1.js?t=20121204的脚本,两者相同】
a.sso的内容
"http://sso.360buy.com/setCookie?t=sso.360top.com&callback=?"
"http://sso.360buy.com/setCookie?t=sso.minitiao.com&callback=?"
"http://sso.360buy.com/setCookie?t=sso.ehaoyao.com&callback=?"
"http://sso.360buy.com/setCookie?t=sso.jcloud.com&callback=?"
"http://sso.360buy.com/setCookie?t=sso.qianxun.com&callback=?"
4.客户端回调函数,遍历a.sso,逐个发起getjson 请求(此时请求目标还是在同一个主域名下,firebug网络面板中setcookie系列请求,如下图),
相关代码: $.each(a.sso, function () { $.getJSON(this) })
http请求:
![](http://images0.cnblogs.com/blog/129849/201305/17083625-d62f78ebe9a14be2b9ca26f17c6c99b1.png)
5.setcookie系列请求,各自响应一个与setcookie所接受的t参数相应域名的jsonp请求地址(即是接下来的跨域请求),并包含统一的一个c参数
![](http://images0.cnblogs.com/blog/129849/201305/17083643-00d88dabff884ea398dc393f29c5d97d.png)
*5到6的衔接,猜测是setcookie的响应同时触发了sign系列的请求,那必须返回一个js代码片段,发起getjson请求。
6.客户端发起sign系列请求,包含c参数,跨主域名请求,响应即为设置ceshi3.com cookie
http://sso.360top.com/sign? c=6d324d99805593c4aac6abfdd17e67399d73......54763628040
http://sso.minitiao.com/sign?c=6d324d99805593c4aac6abfdd17e67399d73......54763628040
http://sso.jcloud.com/sign? c=6d324d99805593c4aac6abfdd17e67399d73......54763613889
http://sso.ehaoyao.com/sign? c=6d324d99805593c4aac6abfdd17e67399d73......54763613889
http://sso.qianxun.com/sign? c=6d324d99805593c4aac6abfdd17e67399d73......54763613890
(上面省略的部分包含了类似“48bd&callback=jsonp1354763638164&_=1354763638814&t=1354763”)
7.所有京东涉及登陆信息的页面,可对ceshi3.com cookie进行解析,以此作为登陆凭证。
**可以验证一下
登陆京东后,打开京东奢侈品(360top),删除cookie ceshi3.com 刷新后显示未登陆,再打开京东迷你挑(此时又同步了一次cookie),再回京东奢侈品(360top),刷新后依旧是登陆状态。(迷你挑测试中偶尔会有问题,可以换一个京东产品试试)
8.退出时,跳转到登出页面,JS发起getjson请求,删除所有cookie
京东登出页上找到以下代码
点击(此处)折叠或打开
- <script type="text/javascript">
- jQuery.getJSON("http://sso.360top.com" + "/exit?callback=?");
- jQuery.getJSON("http://sso.qianxun.com" + "/exit?callback=?");
- jQuery.getJSON("http://sso.ehaoyao.com" + "/exit?callback=?");
- jQuery.getJSON("http://sso.360buy.com" + "/exit?callback=?");
- jQuery.getJSON("http://sso.minitiao.com" + "/exit?callback=?");
- jQuery.getJSON("http://sso.jcloud.com" + "/exit?callback=?");
- </script>
总结,整体的关键在于360buy.com下客户端js发起jsonp跨域请求时,传递的参数c(猜测是对称加密后的数据,与登录凭据cookie ceshi3.com 的值有对应关系)。其他细节都在于服务器端对各系列请求的处理。
如果A域名和B域名(指主域名不同的情况)要共享登陆
B域名下的cookie还是要B自己写的,jsonp的处理就是告诉B,该写个什么值,当然传递过程中最好进行加密(上面的参数c)。当ABCD等等各产品都设置了统一的凭据,那么就完成了“单点登陆”的要求。不过,对这个凭据进行解析的需求也是很重要的,这里倒未提及。因为涉及到ceshi3.com这个cookie里信息的具体内容,这个验证过程也只有京东的开发人员才知道了。