使用 P3P 规范让 IE 跨域接受第三方 cookie

本文探讨了在IE浏览器下设置第三方cookie遇到的问题及解决方案,包括调整IE设置、部署P3P规范以及通过HTTP header等方式,重点解决了单点登录(SSO)场景中IE无法接收cookie的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前两天尝试使用 jsonp 跨域提交用户名密码请求,实现自动登录第三方网站,即 SSO(single-sign-on) 单点登录,一处登录处处登录。在 Firefox下没问题,IE 却不行。查看 HTTP 的几个来回,发现登录请求是成功的,问题出在第三方网站返回的 cookie (session id) IE 并没有接受,下一次发送请求时根本没有带上 cookie,说明之前的 Set-Cookie 指令没有效果,所以怎么也登录不了。查了一下,有人使用 iframe 内嵌网页的形式,也遇到了 IE 下不能设置 cookie 的情况。

如果在“Internet选项”->“隐私”->“高级”中把“替代Cookie自动处理”勾选上(这是IE9的设置,版本低的IE需要把隐身级别设置为低,就没问题了。但是我们不可能让每个用户去更改 IE 设定吧?这是一个很常遇到的场景,肯定有别的解决办法。

浏览器的第三方 cookie 限制

所谓第三方 cookie,就是说你访问网页 A,却接收到域名 B 的 cookie 设定指令。这可能是由于网页 A 请求或链接了 B 的网页,比如上面提到的 iframe 以及 jsonp。

我查到了各个浏览器对于跨域的处理规则,可以看到第三方 cookie ,IE 在默认设置中是做了限制的。

不同浏览器的第三方 cookie 规则
 

IE

FireFox

Chrome

Safari

Opera

限制第三方coookie

要解决这个问题,有 2 种方法,一个就是上面说到的调整 IE 设置,将第三方域名加入到可信网站列表中;另一个方法,就是 P3P 了。

P3P?

P3P 全称 Platform for Privacy Preferences,隐私设定平台规范。这个规范极其复杂,若要讲清楚,天都黑了一半。简言之,就是网站向浏览器声明自己的隐私政策,比如网站是否搜集访问者的个人信息,设置 cookie 的用途等等。浏览器会依据设置,决定在第三方请求的条件下是否接受网站的 cookie。

完整地部署 P3P 包括设立隐私政策文件(policy.html)、原则档(policy.xml)、参考档(p3p.xml),有兴趣详细了解的可以参考 MSDN 中关于部署 P3P的文章。

这搞得太复杂了,我只是想在公司内部做各个管理系统的单点登录而已。好在还是有比较简单的方法的,就是发送 P3P 相关的 HTTP header。

ASP.NET:

HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");  

PHP:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); 

JSP:

response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'"); 

好吧,这些 IDC DSP 什么的是啥意思啊?

这些标签就是 P3P 所规定的了,例如 NOI 表示不搜集可识别用户的资料,ADM 表示信息搜集会用于网站管理……

浏览器会根据这些标签决定是否接受 cookie,根据测试结果,加上 NOI 最省事,一个就够了。不过网站一般很难做到 NOI,除非永远匿名,“登录”功能可能就违背了NOI。理论上讲,标签应该真实地反映网站的信息搜集行为,若声明的隐私政策与实际行为不符,是会要负法律责任的。Stackoverflow 有篇讨论提出了法律相关议题,可以参考。

除了传送 P3P http header,还可以通过 HTML meta 标签,或者 设定 IIS 服务器 来声明 P3P。

参考链接:http://www.lovelucy.info/ie-accept-third-party-cookie.html

PS:查看好几篇类似JSP中使用P3P解决跨域的方法,发现P3P的值不太一样,但在IE9下都是正确的,在此记录一下

response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'");
response.setHeader("P3P","CP=\"NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC\"");
response.setHeader("P3P","CP=CAO PSA OUR");
response.setHeader("P3P","CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'");


### 解决 iframe 中 Cookie 丢失的方法 #### 使用 P3P 头部解决 IE 浏览器中的问题 对于 Internet Explorer (IE),支持的 P3P 协议会默认阻止第三方无隐私安全声明的 cookie,在请求中不会在 header 中发送(设置)cookie 信息。为了使 IE 不再阻止这些 cookies,可以在 HTTP 响应头中添加 `P3P` 字段[^1]。 ```java public class P3PFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setHeader("P3P", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""); chain.doFilter(request, response); } // Other methods... } ``` 此过滤器会在每个响应头部加入指定的 P3P 隐私策略字符串,使得浏览器能够接受来自不同名框架内的 cookie 设置。 #### 应用 CORS 或 JSONP 实现数据交互 当遇到因同源政策而无法正常工作的场景时,可以考虑采用资源共享(CORS)[^2]的方式允许服务器端配置特定资源可被哪些外部站点访问;或者是通过 JSONP 技术绕过同源限制完成简单的 GET 请求操作。不过这两种方法主要适用于 API 接口调用而非直接处理 session/cookies 的情况。 #### 利用顶级导航重定向机制 另一种常见的做法是在首次加载 iFrame 页面之前先执行一次顶级窗口位置改变的动作,即让用户短暂离开当前页面并立即返回原址,这样做的目的是为了让用户的浏览器认为这是第一次访问目标网站而不是嵌套浏览环境的一部分,进而正确保存和读取相关的认证凭证或会话信息。 以上三种方式可以根据实际需求和技术栈特点灵活选用一种或多组合起来使用以彻底解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值