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,可以设置成不同的标识这样也不会相互覆盖,也就不会出现掉线的情况。
 
 
-------------------------------
我目前在做一个电子购物网站。这个网站对应着不同的国家,将会有不同的域名。比如,对英国会是www.xxx.com.uk,对中国可能是www.xxx.com.cn。但是,在涉及到支付时,都会转向一个地址:https://checkout.xxx.com。这些不同的域名,实际上是指向同一台服务器的同一个Server。 

在实际使用中,由于域名不同,但又需要跨域访问。主要应用场景是,客户在英国的购物网站-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丢失的问题的更多相关文章

  1. cors解决Web跨域访问问题

    首先了解一下什么是跨域以及解决的几种常见方式. 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 所谓同源是指,域名,协议,端口均相同. 举例: 相对于 ...

  2. Spring Boot+AngularJS中因为跨域导致Session丢失

    http://blog.csdn.net/dalangzhonghangxing/article/details/52446821 如果还在为跨域问题烦恼,请查看博主的 解决angular+sprin ...

  3. express解决ajax跨域访问session失效问题

    最近在学习express,就用以前做的项目来进行express前后端分离的练手了,在做登陆注册的时候发现跨域的时候,session的值是会失效的,导致session里面的数据获取为undefined, ...

  4. Vue axios 跨域访问Session,两次得到的Session不是同一个Session

    这个问题是因为,后台无法确认你是同一个“人”访问服务器,两次访问都给了你一个全新的Session,所以第一次保存的信息第二次请求无法得到,我的理解是,在跨域中,携带Cookie信息访问,即可让服务器确 ...

  5. 解决getJSON跨域登录Session丢失的问题

    最近在做项目中发现,我用下面的代码异步请求到login.ashx: var memberUrl = rooturl + 'member.ashx?r=' + Math.random() + '& ...

  6. 在IE浏览器中iframe跨域访问cookie/session丢失的解决办法

    单点登录需要在需要进入的子系统B中添加一个类,用于接收A系统传过来的参数: @Action(value = "outerLogin", results = { @Result(na ...

  7. 在ABP的Web层中实现复杂请求跨域访问

    在最近的项目中,后端使用ABP,前端采用React,前后端完全分离.其中大部分接口都通过WebApi层调用,项目中未使用Session.但最后在添加一个网站的验证码验证留言功能时,使用了Session ...

  8. SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)

    上个示例(SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API))是基于JavaScript,运行在web browser内去访问REST AP ...

  9. URL资源跨域访问 跨域使用session信息

    SilverLight 出于对安全性的考虑默认情况下对URL的访问进行了严格的限制,只允许访问同一子域下的URL资源. 下表列出了Silverlight 2.0 中 URL 访问规则:   WebCl ...

随机推荐

  1. 移动端div移动

    <!doctype html> <html lang="en"> <head> <meta http-equiv="Conten ...

  2. Jquery DIV滚动至浏览器顶部后固定不动代码

    $(function(){ //获取要定位元素距离浏览器顶部的距离 var navH = $(".win").offset().top; //滚动条事件 $(window).scr ...

  3. 关于ios “<null>”的异常处理

    在iOS开发过程中经常需要与服务器进行数据通讯,但是在数据接通过程中会出现:null "<null>"等问题导致莫名其妙的崩溃. 相信你一定会写各种判断来处理这些异常, ...

  4. sqlite学习

    一鼓作气,今天继续学习了sqlite数据库在Xcode上的一些操作,主要是通过用oc代码进行salite表格的创建,删除,修改:以及对现有的表格数据进行增,删,改,查.虽然有点累,但是收获不小,感觉很 ...

  5. java 多线程

    1.继承Thread类实现多线程继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是 ...

  6. 重载运算符:类成员函数or友元函数

    类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...

  7. WCF XmlSerializer GetType 反射类型 报错 解决方案

    为图省事,用现有的EF,和web一起使用一个Model类 当进行到 XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType()); 会报 ...

  8. 浅谈JavaScript的作用域

    前段时间学了下JavaScript作用域,这个东西在JavaScript非常重要,也是JavaScript很基础的东西,正如少林里面基础武功,有了基础,才能学绝世武功. 作用域的作用是啥?一套设计良好 ...

  9. appium+Python真机运行测试demo的方法

    appium+Python真机运行测试demo的方法 一,    打开手机的USB调试模式 二,    连接手机到电脑 将手机用数据线连接到电脑,并授权USB调试模式.查看连接的效果,在cmd下运行命 ...

  10. android view:手势

    一直认为android手势识别很是神奇,我们不分析复杂的手势,仅仅是针对上一次的基本事件的手势处理,分析GestureDetector的源码,来看一下到底手势事件是如何定义的. GestureDete ...