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. C#读取大文本文件

    今天偶遇一同事抱怨,sqlserver导出的CSV,明明有1000W条,但用excel打开就只剩100W了,足足消失了90%,所以她怀疑文件是足量的1000W条,是excel捣了鬼.可是文件容量有2G ...

  2. html+css知识点总结(田彦霞)

    html部分 html头部声明 DOCTYPE是document type(文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本.DOCTYPE声明必须放在每一个XHTML文档最顶部,在所 ...

  3. 深入理解JavaScript系列:史上最清晰的JavaScript的原型讲解

    一说起JavaScript就要谈的几个问题,原型就是其中的一个.说了句大话,史上最清晰.本来是想按照大纲式的行文写一下,但写到后边感觉其实就一个概念,没有什么条理性,所以下面就简单按照概念解释的模式谈 ...

  4. MySQL设置字符集为UTF8(Windows版)

    Windows版MySQL设置字符集全部为utf8的方式 MySQL安装目录下的my.ini文件 [client]节点 default-character-set=utf8    (增加) [mysq ...

  5. fatal: Could not read from remote repository.的解决办法

    1. git remote –v查看远端地址或者查看配置 git config –list 2. git status 3. git add . git status git commit -m “本 ...

  6. Android 开发常用命令

    1.生成keystore文件 keytool -exportcert -keystore keystore_path -list -v 2.查看APK签名 keytool -list -printce ...

  7. 1、MVC和EF中的 Model First 和 Code First

    准备:先引入MVC和EF的dll包 *命令方法:打开工具——库程序包管理器——程序包管理器控制台,选择自己的项目 a)     Install-Package EntityFramework -Ver ...

  8. Autorun.inf文件(2):改变硬盘分区图标

    改变F盘图标. 原理:在f盘下新建一个Autorun.inf文件,文件内容是 [AutoRun]icon=favicon.ico准备名为favicon.ico图标文件,将其放在工程目录里,设计程序将它 ...

  9. centos安装与卸载postgresql

    1.卸载旧版本postgresql $ yum remove postgresql* 2.更新yum $ yum update 3.下载pgdg-centos92-9.2-6.noarch.rpm,或 ...

  10. cocos2d-x iOS真机下载非根目录文件提示下载失败解决办法

    在使用cocos api的Downloader或者AssetsManager下载文件到真机Document目录时,如果是直接下载到document根目录,是没问题的,如果是下载存放到了某个不存在的子目 ...