问题来源
最近开发的ssh框架项目,要进行上线,因为项目中设计了登录权限,需要用到session来存储信息,在进行接口联调的时候才得知运营人员是使用iframe进行接口调用的,联调时发现接口可以直接在浏览器地址栏访问并加载出界面数据,在使用iframe调用时数据加载不出来
分析问题
在后台经过分析打印的日志得知,调用接口时程序获取不到session信息,故不能获取用户信息,程序会终止请求。
那么为什么直接在地址栏请求接口,后台能获取到session,使用iframe却获取不到呢,在网上查阅资料说是iframe跨域造成的session数据丢失,需要在http响应头中设置P3P(P3P是一种被称为个人隐私安全平台项目(the Platform for Privacy Preferences)的标准,能够保护在线隐私权,使Internet冲浪者可以选择在浏览网页时,是否被第三方收集并利用自己的个人信息。如果一个站点不遵守P3P标准的话,那么有关它的Cookies将被自动拒绝,并且P3P还能够自动识破多种Cookies的嵌入方式),
解决问题
根据网上资料说在响应头添加p3p信息:(可在代码中保存session信息的位置添加)
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("P3P","CP='CAO IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'");
设置好之后再次访问接口,依旧没有数据,通过控制台查看网络调用情况
从网络请求可以看出相应头中已经加入了p3p,同时又发现了另一个参数set-cookie该参数最后有个警告符号,因为截图截不到,所以就直接在下方写出来了。
this set-cookie did not specify a ‘SameSite’ attribute and was defaulted to “SameSite=Lax” and broke the same rules specified in the SameSiteLax value
大致意思为:这个set-cookie没有指定“SameSite”属性,默认为“SameSite=Lax”,并且违反了在SameSiteLax值中指定的相同规则
那么什么是 SameSite
*SameSite是cookie的一个属性,用来限制第三方Cookie。
SameSite有三个值可以设置
Strict(禁止第三方 cookie)
Lax(稍微严格一点)
None (注意,cookie的SameSite设置为None以后,Secure需要同时设置为true,这意味着你的网站必须支持https)
这是在网上找的一张图可以直观查看samesite各属性作用范围(侵删)
原来是samesite的原因导致第三方(iframe中src指定的地址)cookie被禁用,进而导致session丢失,而samesite默认为Lax 而iframe正好在被禁之列。
那么怎么才能解决samesite这个问题呢
- 保证调用方与被调用方,地址在同一个域名下,不存在跨域就不会有这个问题
- 设置SameSite=None,启用https
- 在chrome浏览器的地址栏输入:chrome://flags/ 然后在搜索框输入:cookie,找到Enable removing SameSite=None cookies;SameSite by default cookies,将这两个状态改为:desabled
- 使用Nginx代理访问端口(推荐使用)
浏览器配置如下
值的注意的是,在新版本的google浏览中,上述两个选项已经被取消,浏览器将samesite=Lax设置为了默认项
如果开发调试的时候用的版本比较新可以使用以下方式(nginx代理):
我这样做的思想是将调用方a,与被调用方b,两个服务的站点用同一个ip来操作,这样就不会有跨域的问题,代码如下
server {
listen 8080;
server_name c.c.c.c;#nginx所在服务器ip
location / {
proxy_pass http://a.a.a.a:2081;#a服务站点(调用方)
}
location /b {
proxy_pass http://b.b.b.b:8084;#b服务站点(iframe src指向的服务)
}
}
此时a,b服务调用都使用nginx的c.c.c.c:8080加上配置代理路径来访问,固两个服务的ip+port都相同,不存在跨域,当在a服务中使用iframe调用b服务时浏览器不拦截cookie
其它nginx代理可参考:
http://t.csdn.cn/SpySN