当前位置

跨域(cross-domain)访问 cookie (读取和设置)

Passport 一方面意味着用一个帐号可以在不同服务里登录,另一方面就是在一个服务里面登录后可以无障碍的漫游到其他服务里面去。坦白说,目前 sohu passport 在这一点实现的很烂(不过俺的工作就是要把它做好啦,hehe)

搜狐的 SSO 需求比较麻烦,因为它旗下有好多域名:sohu.com、chinaren.com、sogou.com、focus.cn、17173.com、go2map.com,登录用户漫游的主要障碍也来自于此。

以前亿邮的邮件系统在和别的系统整合的时候是提供一个 URL,用户从第三方系统里面点击这个链接就可以生成访问邮件界面所需的 cookie,然后进入邮件。这个方式的确很有效,但问题是:
1. 每个外部链接都必须用特殊的 URL 跳转,维护很麻烦
2. 两个系统集成已经很麻烦了,若是集成的系统有好几个,彼此都需要跳转而缺乏一个中心机制就成了噩梦
3. 根本无法处理用户直接在地址栏输入地址进行访问的情况

即使是跨域,上述的解决方法相对来说还是容易的。
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 控制发现重定向页面成功返回后,就刷新整个页面,让它看起来和用户登录后访问没有什么区别。

下面是真正的技巧:怎样才能在 IE 里面跨域去设置 cookie
上述技术看起来是不是很好?但它的前提是所有的登录都 post 到 sso server 上,认证成功后再返回 app 页面。可我接受到的需求之一就是要支持页面无刷新登录。

哈!就是说本来在 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 之,也没有任何真正可用的答案,中文网页要么介绍的方法是错的,要么说无解。

最后还是在 chinaren 一哥们的帮助下,翻出了他们所使用的,以和 alumni.sohu.com 交互的方法(不知道是哪位牛人发现的),只需要设置 P3P HTTP Header,在隐含 iframe 里面跨域设置 cookie 就可以成功。他们所用的内容是:

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 ,就可以看到新的值了

评论

仔细跟踪学习了一下,然后google果然发现P3P是个很大的未知领域,居然是一个很重要的协议,似乎在这点上IE6比ff要先进,哈哈。
《P3P Web隐私》/oreilly
Google:P3P

如果sohu支持openID,对很多geek来说可是好事
呵呵

现在谈论 openid 为时尚早

没想到这个问题是如此解决的,看来 http 协议对于 web 开发人员来说,是不得不学的,虽然我们已经步入了脚本时代!

呵呵

最后还是在 chinaren 一哥们的帮助下,翻出了他们所使用的,以和 alumni.sohu.com 交互的方法(不知道是哪位牛人发现的)
这个是邹丹发现or发明的
而且不只只是iframe才管用,动态append一个script也可以的

能不能给个例子呢?怎么不懂呢 :) 多谢!!

你想要解决什么问题?

我现在好像知道了。就是我的网页用Iframe引用其他域的网站的页面,那个页面里面使用了session,如果想访问那个网页就要设置允许那个网站的cookie。我看网上说做一个filter,filter里在response里加一个header:response.addHeader("P3P","CP=CAO PSA OUR")就可以解决。我不知道是不是行,因为我现在没俩域,也不知道怎么能弄两个域在我机器上。郁闷。您知道这个方法是否可行呢?

你可以配置自己的域名解析啊

编辑这个文件 c:\windows\system32\drivers\etc\hosts

-_-!!对哦 多谢了啊~~~ :)

你这种方法后来实现了吗?

能给个代码片段看下吗,这几天正被这事折磨着。

关于这点:
4. 点"get corss-domain cookie" .. (此时 js 会去创建一个iframe,请求 qiuyingbo.test.vmx.cn ,返回页面把 cookie 值作为 GET 参数重定向回 dup2.net 的另外一个URL。)

请问可以在iframe中读取cookie么?可不可以给出代码?

只有再当前域下才能拿到 cookie

网页也只能和同一个域名下的 iframe 互相交互数据 (不过为了解决跨域的页面交互问题,firefox 3已经有了解决方案)

我试了一下跨域设置cookie,浏览器的隐私策略默认为中时是无法跨域设置cookie的(p3p)若将隐私策略设为低是没有问题的。你那里是怎么实现的?

P3P HTTP Header

你可以找个工具看看 sohu passport 登陆过程中的交互

非常感谢,我已经实现了和sohu类似的通行证方案,不知道你们各个成员网站的用户信息是如何同步的?难道sohu和chinaren用的是统一的数据库吗?
怎么保证cookie数据的安全性呢?

您好,我最近也在研究跨域cookie读取问题,能否把http://qiuyingbo.test.vmx.cn/cookie.php这个页面的代码给我发一下邮箱呢?我的邮箱是buptlz04@gmail.com,非常感谢

以前的代码不在了,呵呵

写的 很好, 求 源码一阅~ 178458552@qq.com

Howdy! I could have sworn I've visited this web site before but after looking at a few of
the posts I realized it's new to me. Anyhow, I'm definitely
pleased I found it and I'll be bookmarking it and checking
back frequently!