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 ...
随机推荐
- C#读取大文本文件
今天偶遇一同事抱怨,sqlserver导出的CSV,明明有1000W条,但用excel打开就只剩100W了,足足消失了90%,所以她怀疑文件是足量的1000W条,是excel捣了鬼.可是文件容量有2G ...
- html+css知识点总结(田彦霞)
html部分 html头部声明 DOCTYPE是document type(文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本.DOCTYPE声明必须放在每一个XHTML文档最顶部,在所 ...
- 深入理解JavaScript系列:史上最清晰的JavaScript的原型讲解
一说起JavaScript就要谈的几个问题,原型就是其中的一个.说了句大话,史上最清晰.本来是想按照大纲式的行文写一下,但写到后边感觉其实就一个概念,没有什么条理性,所以下面就简单按照概念解释的模式谈 ...
- MySQL设置字符集为UTF8(Windows版)
Windows版MySQL设置字符集全部为utf8的方式 MySQL安装目录下的my.ini文件 [client]节点 default-character-set=utf8 (增加) [mysq ...
- 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 “本 ...
- Android 开发常用命令
1.生成keystore文件 keytool -exportcert -keystore keystore_path -list -v 2.查看APK签名 keytool -list -printce ...
- 1、MVC和EF中的 Model First 和 Code First
准备:先引入MVC和EF的dll包 *命令方法:打开工具——库程序包管理器——程序包管理器控制台,选择自己的项目 a) Install-Package EntityFramework -Ver ...
- Autorun.inf文件(2):改变硬盘分区图标
改变F盘图标. 原理:在f盘下新建一个Autorun.inf文件,文件内容是 [AutoRun]icon=favicon.ico准备名为favicon.ico图标文件,将其放在工程目录里,设计程序将它 ...
- centos安装与卸载postgresql
1.卸载旧版本postgresql $ yum remove postgresql* 2.更新yum $ yum update 3.下载pgdg-centos92-9.2-6.noarch.rpm,或 ...
- cocos2d-x iOS真机下载非根目录文件提示下载失败解决办法
在使用cocos api的Downloader或者AssetsManager下载文件到真机Document目录时,如果是直接下载到document根目录,是没问题的,如果是下载存放到了某个不存在的子目 ...