Passport 一方面意味着用一个账号能够在不一样服务里登陆,另外一方面就是在一个服务里面登陆后能够无障碍的漫游到其余服务里面去。坦白说,目前 sohu passport 在这一点实现的很烂(不过俺的工做就是要把它作好啦,hehe)javascript
搜狐的 SSO 需求比较麻烦,由于它旗下有好多域名:sohu.com、chinaren.com、sogou.com、focus.cn、17173.com、go2map.com,登陆用户漫游的主要障碍也来自于此。php
之前亿邮的邮件系统在和别的系统整合的时候是提供一个 URL,用户从第三方系统里面点击这个连接就能够生成访问邮件界面所需的 cookie,而后进入邮件。这个方式的确颇有效,但问题是:
1. 每一个外部连接都必须用特殊的 URL 跳转,维护很麻烦
2. 两个系统集成已经很麻烦了,如果集成的系统有好几个,彼此都须要跳转而缺少一个中心机制就成了噩梦
3. 根本没法处理用户直接在地址栏输入地址进行访问的状况html
即便是跨域,上述的解决方法相对来讲仍是容易的。
A. 首先是全部登陆必须首先经过一个中央服务器进行认证,而后在它那里给浏览器种下 cookie(下面称之为 sso cookie)
B. 当用户访问另外的域名 app 的时候,浏览器是没法直接发送 sso cookie 给服务器认证的。此时应该利用 javascript,动态建立一个隐藏的 iframe,让其访问 sso
C. 这个 iframe 的请求是能够把 sso cookie 送给 sso server 的。sso server 验证 cookie 后,返回一个重定向页面到 app 的某个 URL,由该 URL 设置 app cookie
D. 此时浏览器上可看见的页面容器实际上也是能够和重定向回来的内容交互的。好比能够用 js 控制发现重定向页面成功返回后,就刷新整个页面,让它看起来和用户登陆后访问没有什么区别。java
下面是真正的技巧:怎样才能在 IE 里面跨域去设置 cookie
上述技术看起来是否是很好?但它的前提是全部的登陆都 post 到 sso server 上,认证成功后再返回 app 页面。可我接受到的需求之一就是要支持页面无刷新登陆。node
哈!就是说原本在 chinaren.com 上提交登陆表单的 action 应该是 passport.sohu.com 这个 sso server。但是在 AJAX 大潮下,chinaren 计划采用 XMLHTTPRequest 提交,这个就麻烦了,由于是不能跨域来提交的。跨域
那么解决方法就是跨域产生 cookie,即 js 发现口令校验成功后,再在 passport.sohu.com 上种上合法的 cookie.浏览器
套用上面的跨域读 cookie 的方案彷佛很简单去推论:就是建立一个隐含的 iframe,让那个 iframe 去调用 passport.sohu.com 的 URL 来产生 cookie。很遗憾,此方法在 Fx 下工做的很好,可是不能在 IE 上应用。(在 IE 状态栏上显示 cookie 隐私警告,红色圆底白横杠)服务器
我试了不少不少方法,包括建立 、 node,包括用 js 设置,但都一次次被 IE 无情的挡在了浏览器外。google 之,也没有任何真正可用的答案,中文网页要么介绍的方法是错的,要么说无解。cookie
最后仍是在 chinaren 一哥们的帮助下,翻出了他们所使用的,以和 alumni.sohu.com 交互的方法(不知道是哪位牛人发现的),只须要设置 P3P HTTP Header,在隐含 iframe 里面跨域设置 cookie 就能够成功。他们所用的内容是:app
P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"
最后是我作的一个小小的演示:cookie 怎么在 vmx.cn 和 dup2.net 之间交互
1. http://qiuyingbo.test.vmx.cn/cookie.php
2. 随便输入什么,点 reset cookie,就能够看到 vmx.cn 的 cookie 已经被设上了
3. 在该页面点链接到 http://www.dup2.net/vmx/cookie.html
4. 点"get corss-domain cookie" .. (此时 js 会去建立一个iframe,请求 qiuyingbo.test.vmx.cn ,返回页面把 cookie 值做为 GET 参数重定向回 dup2.net 的另一个URL。)
5. 点 "display corss-domain cookie" .. 就能够看到 vmx.cn 的 cookie 了
6. 在该页面的输入框中输入其它的值,而后点 "set cross-domain cookie",该行为将主动设置 vmx.cn 的 cookie
7. 点连接回到 http://qiuyingbo.test.vmx.cn/cookie.php ,就能够看到新的值了
网上看了别人介绍的一片文章,说使用P3P能够完成跨域COOKIE操做,感受很COOL,不过没有提供源代码,我胡乱写了一下,你们看看。
实际工做中,相似这样的要求不少,好比说,咱们有两个域名,咱们想实如今一个域名登陆后,能自动完成另外一个域名的登陆,也就是PASSPORT的功能。
我只写一个大概,为了测试的方便,先编辑hosts文件,加入测试域名(C:\WINDOWS\system32\drivers\etc\hosts)
127.0.0.1 www.a.com
127.0.0.1 www.b.com
首先:建立 a_setcookie.php 文件,内容以下:
<?php
//header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("test", $_GET['id'], time()+3600, "/", ".a.com");
?>
而后:建立 a_getcookie.php 文件,内容以下:
<?php
var_dump($_COOKIE);
?>
最后:建立 b_setcookie.php 文件,内容以下:
<script src="http://www.a.com/a_setcookie.php?id=www.b.com"></script>
----------------------------
三个文件建立完毕后,咱们经过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
咱们会发现,在访问b.com域的时候,咱们并无在a.com域设置上cookie值。
而后咱们修改一下a_setcookie.php文件,去掉注释符号,a_setcookie.php即为:
<?php
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("test", $_GET['id'], time()+3600, "/", ".a.com");
?>
再次经过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
此次,你会发如今访问b.com域的时候,咱们设置了a.com域的cookie值。
末了补充一句,彷佛只有IE对跨域访问COOKIE限制比较严格,上述代码在FIREFOX下测试,即便不发送P3P头信息,也能成功。不过IE是老大啊。