通过设置P3P头来实现跨域访问COOKIE
实际工作中,类似这样的要求很多,比如说,我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是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头信息,也能成功。
==========================================
通过Fiddler可以方便的知道上面P3P代码的含义
P3P Header is present:
CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"
Compact Policy token is present. A trailing 'o' means opt-out, a trailing 'i' means opt-in.
CURa
Information is used to complete the activity for which it was provided.
ADMa
Information may be used for the technical support of the Web site and its computer system.
DEVa
Information may be used to enhance, evaluate, or otherwise review the site, service, product, or market.
PSAo
Information may be used to create or build a record of a particular individual or computer that is tied to a pseudonymous identifier, without tying identified data (such as name, address, phone number, or email address) to the record. This profile will be used to determine the habits, interests, or other characteristics of individuals for purpose of research, analysis and reporting, but it will not be used to attempt to identify specific individuals.
PSDo
Information may be used to create or build a record of a particular individual or computer that is tied to a pseudonymous identifier, without tying identified data (such as name, address, phone number, or email address) to the record. This profile will be used to determine the habits, interests, or other characteristics of individuals to make a decision that directly affects that individual, but it will not be used to attempt to identify specific individuals.
OUR
We share information with ourselves and/or entities acting as our agents or entities for whom we are acting as an agent.
BUS
Info is retained under a service provider's stated business practices. Sites MUST have a retention policy that establishes a destruction time table. The retention policy MUST be included in or linked from the site's human-readable privacy policy.
UNI
Non-financial identifiers, excluding government-issued identifiers, issued for purposes of consistently identifying or recognizing the individual. These include identifiers issued by a Web site or service.
PUR
Information actively generated by the purchase of a product or service, including information about the method of payment.
INT
Data actively generated from or reflecting explicit interactions with a service provider through its site -- such as queries to a search engine, or logs of account activity.
DEM
Data about an individual's characteristics -- such as gender, age, and income.
STA
Mechanisms for maintaining a stateful session with a user or automatically recognizing users who have visited a particular site or accessed particular content previously -- such as HTTP cookies.
PRE
Data about an individual's likes and dislikes -- such as favorite color or musical tastes.
COM
Information about the computer system that the individual is using to access the network -- such as the IP number, domain name, browser type or operating system.
NAV
Data passively generated by browsing the Web site -- such as which pages are visited, and how long users stay on each page.
OTC
Other types of data not captured by the above definitions.
NOI
Web Site does not collected identified data.
DSP
The privacy policy contains DISPUTES elements.
COR
Errors or wrongful actions arising in connection with the privacy policy will be remedied by the service.
Validate at: http://www.w3.org/P3P/validator.html
Learn more at: http://www.fiddlertool.com/redir/?id=p3pinfo
作者是老王 http://hi.baidu.com/thinkinginlamp/blog/item/5e2a02084f1dafd163d9865f.html
另外,他参考的文章是:http://www.dup2.org/node/384
以下是内容:
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 ,就可以看到新的值了