web跨域访问,session丢失的问题
web跨域访问,session丢失的问题25
http://www.iteye.com/problems/71265
http://www.iteye.com/topic/264079
现有项目A和项目B, 项目A中有项目B的一个链接,点击此链接传递过去用户名和密码登陆到B项目中去,此时B项目作为A项目的一个页面出现,第一次点击链接时操作没有问题,当返回来点击A项目链接时提示掉线。
以下为项目部署说明:
项目A用到了集群,apache+tomcat 没有采用session复制,其中A项目也是通过统一门户点击链接进入,并且A项目链接B项目时用到了frameset框架。门户网站也是通过apache转发过来。
现在问题是进入A项目后,如果不点击B项目链接,没有任何问题,只要点击了B项目链接,回过来点A项目的其他菜单即提示掉线(即session为空)
开始的时候点击B项目链接的时候也掉线,后来在B项目加了一个头 P3P什么的解决了。
此问题我想了两天不知何因,求解。
问题补充:问题原因很简单,因为在同一域名下,用的又都是tomcat,而tomcat默认在cookie里放得session的标识是jsessionid,所以点击不同项目的时候jessionid会覆盖上个jsessionid,这样再点击回来的时候会造成jsessionid被覆盖,tomcat根据jessionid找不到session,也就会掉线。有以下几种解决方式:1.改变项目的的cookie path,如果是域名的话,可以将几个项目的域名设为不同。2.可以采用其他的web容器,如jetty或者weblogic,这些容器都可以设置session的标识jsessionid,可以设置成不同的标识这样也不会相互覆盖,也就不会出现掉线的情况。
在实际使用中,由于域名不同,但又需要跨域访问。主要应用场景是,客户在英国的购物网站-http://www.xxx.com.uk(简称:uk站) 中往购物车中放置了商品,最后,转至https://checkout.xxx.cml来进行支付工作。这时就碰到了跨域访问时,Session丢失的问题。
先说一下,我们用的服务器是Tomcat。Tomcat是通过url中的jsessionid以及cookie中的jsessionid来取得会话ID的。Tomcat先会查询URL后面有没有跟jsessionid。然后,再去解析Cookie中的jsessionid。如果cookie中有的话,那么,不管之前从URL中有没有找会jsessionid,都会使用cookie中找到的。详情参见Tomcat中的CoyoteAdapter类。
问题1:我打开浏览器,在uk站中买了一件商品,当我点击页面中的Check Out链接时,页面跳入了https://checkout.xxx.com的支付页面后,用户购物车里的商品在跳转在支付页面中消失了。
问题原因:由于两者的域名不同,在跳转到支付页面时,丢失了原来的会话信息。无论是URL还是cookie中都找不到会话ID了。Tomcat创建了一个空空如也的新会话。
解决办法:重写链接,在支付链接后加上jsessionid,也就是像这样https://checkout.xxx.com;jsessionid=A8AB5D19484BFCF26E8E4F708E2F6C91.jvm1。在转到支付页面时,由于此时浏览器中https://checkout.xxx.com域名的cookie中没有任何信息,则Tomcat会使用URL中取得的sessionId。这样,就能继续使用uk站中的会话了。
问题2:通过URL重写,我们可以在https://checkout.xxx.com的页面能够看到购物网站的信息了,我本以为一切到此结束了,没想到,又出现了新的问题。在支付过程中,页面使用Ajax和服务器做些数据的交互。可每次交换,服务器居然都报session中找不到用户登录信息的exception。仔细看了下日志,服务器在处理支付页面上的初次的Ajax请求时,居然创建了一个新的Session。
问题原因:在通过Ajax发送请求时,Tomcat无法从URL中取得会话ID,之后,便试着去Cookie中查询信息。可此时,https://checkout.xxx.com下的cookie竟然是空空如也的。之前从购物网站跳转至https://checkout.xxx.com时,Tomcat从URL中取得了原会话ID。此时,Tomcat是继续使用原有session,而没有创建新的session,便没有向浏览器的cookie写入信息JSESSIONID的信息了(这是我猜测的,没看代码证实过)。
解决办法:既然能在转入支付页面时使用原有的Session,那么,就在刚转入支付页面时,把sessionid写入cookie不就行了吗?这里我暂时用js把sessionid写入了cookie中。之后做了几次测试都顺利地通过了。
问题3:好了,当我以为一切都OK的时候,又出现了一个问题。我先打开www.xxx.com,也就是checkout.xxx.com的主域名。接着再打开www.xxx.com.uk进行购买的操作。此时,当我转入https://checkout.xxx.com时,session又丢失了。
问题原因:其实,这里的session没有丢失。通过SessionID来看,在转入https://checkout.xxx.com时,由于之前打开了其主域名www.xxx.com,在cookie中留下了host为xxx的session的信息。而在从购物网站转入支付页面时,Tomcat先从URL中取得了uk站的会话ID,但是最后又从cookie中取到了www.xxx.com的会话ID,并且使用了它。
解决办法:暂无。
候选办法1:修改Tomcat中的CoyoteAdapter类,让它以URL中的jsessionid为主,以cookie中的为辅。但是,这样做就会有个很大的问题。那就是,如果用户收藏了一个购物站中的一商品的链接。而这个链接后面又跟了一个已经失效的jsessionid,那么,服务器端会由于拿不到这个失效的jsessionid对应的Session,而去创建一个新的会话。这样子,就很有可能在同一个浏览器中访问相同的站点,但却面对着不同的会话。
候选办法2:让公司再单独开个域名,专门负责处理check out。在进入这个域名前,对header中的referer信息进行验证,如果来自购物网站,则对请求进行正常处理。反之,则重定向到其它的域名。不知道重写向时,会不会向cookie中写入信息?这个不知道可行否。
不知道各位对应问题3的情况有什么处理建议吗?还望大家不吝赐一二呀。
PS. 据说,SSL证书是针对域名收钱的。所以,我们针对不同国家或有不同的域名。但对于支付,都是跳转到https://checkout.xxx.com这一个来进行的。这样,只需要一张SSL证书就行了。
补充:目前我们都只是在做一个国家的站点,checkout测试也是针对一个国家的。但实际上,各个不同的国家的站点,其实是不同的webapp。它们在支付时都会转向的那个checkout网站,也只能是个独立的webapp了。那么,这就不是单靠个sessionid就能和各个国家的站点共享他们的session的问题了。 而是两个不同的应用间,共享数据的问题了。
兜了圈子,猛然发现,现在我在努力解决的问题,不是将来要实际面对的问题。狂汗。
web跨域访问,session丢失的问题的更多相关文章
- cors解决Web跨域访问问题
首先了解一下什么是跨域以及解决的几种常见方式. 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 所谓同源是指,域名,协议,端口均相同. 举例: 相对于 ...
- Spring Boot+AngularJS中因为跨域导致Session丢失
http://blog.csdn.net/dalangzhonghangxing/article/details/52446821 如果还在为跨域问题烦恼,请查看博主的 解决angular+sprin ...
- express解决ajax跨域访问session失效问题
最近在学习express,就用以前做的项目来进行express前后端分离的练手了,在做登陆注册的时候发现跨域的时候,session的值是会失效的,导致session里面的数据获取为undefined, ...
- Vue axios 跨域访问Session,两次得到的Session不是同一个Session
这个问题是因为,后台无法确认你是同一个“人”访问服务器,两次访问都给了你一个全新的Session,所以第一次保存的信息第二次请求无法得到,我的理解是,在跨域中,携带Cookie信息访问,即可让服务器确 ...
- 解决getJSON跨域登录Session丢失的问题
最近在做项目中发现,我用下面的代码异步请求到login.ashx: var memberUrl = rooturl + 'member.ashx?r=' + Math.random() + '& ...
- 在IE浏览器中iframe跨域访问cookie/session丢失的解决办法
单点登录需要在需要进入的子系统B中添加一个类,用于接收A系统传过来的参数: @Action(value = "outerLogin", results = { @Result(na ...
- 在ABP的Web层中实现复杂请求跨域访问
在最近的项目中,后端使用ABP,前端采用React,前后端完全分离.其中大部分接口都通过WebApi层调用,项目中未使用Session.但最后在添加一个网站的验证码验证留言功能时,使用了Session ...
- SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
上个示例(SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API))是基于JavaScript,运行在web browser内去访问REST AP ...
- URL资源跨域访问 跨域使用session信息
SilverLight 出于对安全性的考虑默认情况下对URL的访问进行了严格的限制,只允许访问同一子域下的URL资源. 下表列出了Silverlight 2.0 中 URL 访问规则: WebCl ...
随机推荐
- fvvk
Hello world! D1C0E3D12E624362B9F8D55ABA2E0FB8,D1C0E3D12E624362B9F8D55ABA2E0FB9
- freeCAD文档结构
一个freecad文档包含了你场景中的所有物体.它可以包含组及任何工作平台制造的物体.你可以切换工作台,但是它仍然工作在同一个文档上.当您保存您的工作时,该文件就被保存到磁盘上.你可以同时打开多个fr ...
- jpa 表字段转bean对象
select 'private ' || decode(v_type, 'int', 'Integer', 'float', 'Double', 'date', 'Date', 'String') | ...
- iOS中修改头部tabBarButton 默认按钮的颜色和默认字体颜色
+(void)initialize { //初始化设置主题 UINavigationBar *navBar = [UINavigationBar appearance]; [navBar setBac ...
- 64位系统下找不到office 32位组件
如果系统式64位的,而装的是32位的office软件,在运行栏中输入命令:dcomcnfg,打开组件服务管理窗口,但是却发现找不到Microsoft Excel程序, 这主要是64位系统的问题,exc ...
- 自增序号,而且默认变量就是$i,也就是说在你的volist标签之内,可以直接使用$i
<volist name="vlist" id="v"> <{$i}> // 直接使用$i </volist>
- UE4 VR GUI实现 参考(UMG AND VR)
Note:4.13以后版本VR UI采用 WidgetComponent + WidgetInteractionComponent可轻松实现交互 Blueprint Demo: https://for ...
- BackTrack5-r3虚拟机安装
ISOL INUX 3.63 Debian-2008-07-15 Copyright (C) 1994-2008 H. Peter Anvinboot:(按回车) 选择:BackTrack Text ...
- LayaAir引擎——(六)
LayaAir引擎——TiledMap地图图块属性获取和进行墙壁碰撞检测 需要的软件: TiledMap LayaAir IDE 1.0.2版本 所画的地图: pass层: floor层: pass层 ...
- C#字符串截取
.取前i个字符 ,i); string str1=str.Remove(i,str.Length-i); .去掉前i个字符 ,i); string str1=str.SubString(i); .从右 ...