第三方支付过程中session失效问题
第三方支付过程中session失效问题
问题产行于公司p2c交易平台的一个用户充值模块。
平台简介:该平台通过第三方支付(以下使用“支付宝”代替)完成与各大银行的交易(充值、投资、转帐、提现等操作),并将数据保存在我司的服务器数据库中,服务器使用tomcat,数据库Mysql
平台充值流程:用户登陆系统----点击充值-----跳转到支付宝----登陆支付宝------选择银行------充值完毕-----redrect到用户中心(平台中的action为"preurl:/user/center"),问题来了,
当用户充值完成后转回用户中心时平台转回了登陆界面,需要用户重新输入一次用户名和密码才能到达用户中心。
谈到此种现象,但凡搞过java开发的软件工程师应该都能想到是session问题,好吧,让我们来一起研究一下从点击充值到支付完成过程中session的变化。
1、用户使用username 和 password登陆后会将用户信息保存在session中,并且在客户端浏览器的cookie中添加一个cookie(key:JSESSIONID,value:XXX);
2、用户点击充值按钮跳转到支付宝---XX银行进行充值,由于XX银行充值网站也是使用tomcat,那么cookie中默认的session key 也为 JSESSIONID,这样以来充值完毕便修改了cookie中session的值;
3、平台使用spring security的用户登陆校验,拦截所有需要用户登陆的界面,这样以来,当充值完成返回preurl:/user/center的时候被spring拦截,并取出cookie中JSESSIONID所对应的值再去session里查找用户信息;
4、由于XX银行修改过的session与原session并非同一session,于是spring将其拦截到用户登陆界面;
以上便是一个很常见的跨域访问session失效问题,但是问题并非想象中那么简单,至少笔者在此问题上费了很大的力气,并寻问“众大神”以及几千人的技术群,无一人知晓(或许真正的大神不屑一顾吧),现解决办法及说明总结如下:
1、总体思路
在用户点击充值时将sessionid保存下来,充值成功后再将sessionid取出来替换
2、具体实现
支付宝接口说明中有一个字段叫做merpri(私有域),官方解释:“用户自定义字段,可以将自己需要
的信息保存在里面,接口调用完成后原样返回”,那么正好是我们需要的,在向支付宝write数据时,我将sessionid取到并放入merpri中,然后在回调时将merpri中的值取出,通过遍历cookie数组将数组中名为JSESSIONID的cookie替换为之前的,关键代码如下:
//说明:以下代码为直接在博客中手写如有错误请留言,以便及时更正
//从jsf中获取
HttpServletRequest request = FacesUtil.getHttpServletRequest ();
HttpServletResponse response = FacesUtil.getHttpServletResponse();
//从支付宝返回参数中获取之前保存的sessionid
String finalSession = request.getParameter("merpri");
Cookie[] cookies = request.getCookies();
for(Cookie c : cookies){
if(c.getName.equals("JSESSIONID")){
//如果是带域名的网站需要配置,因为现在的问题是跨域session失效
c.setDomain(".alibaba.com");
//删除cookie
c.setMaxAge(0);
//设置路径(域名后面的主路径)
c.setPath("/alibaba");
response.addCookie(c);
c.setDomain(".alibaba.com");
Cookie cookie = new Cookie("JSESSIONID",finalSession);
//设置生命周期为20分
cookie .setMaxAge(20);
cookie .setPath("/");
response.addCookie(cookie);
}
}
3、容易出问题的地方总结:
1) 不要将代码放在耦合性较强的代码逻辑中
2) cookie中sessionid的操作一定要在返回/user/center 之前最近位置(否则将无法删除cookie)
3) cookie生命周期和路径一定要注意匹配,应当使用调试工具查看cookie实时的一个值
4) 设置domain时需要特别注意,经本人测试以下四种浏览器:ie 9, firefox, 360安全, 猎豹
其中ie 9 和 firefox域为 .alibaba.com 而360安全,猎豹 的域为www.alibaba.com这样就会出现:使用不同的浏览器设置cookie的域不同而导致其中2个浏览器依然无法正常跳转到用户中心,解决办法:在代码中判断其内核,根据不同的内核设定不同的域。
5) 若使用的第三方支付没有私有域的概念,那么请使用数据库代替吧,即:将sessionid放入数据库中,这样以来要保证事务的完整性了
题外话:
(谈到浏览器的兼容问题,IE浏览器不得不让人大跌眼镜,众所知周,所谓“浏览器兼容”无非就是IE这个“笨重的家伙”,解析js速度慢到极点,并且效果看上去极差,这一点应该向谷歌和火狐学习),360有个新功能是这样描述的:
我们新增加了一个控制手段:内核控制Meta标签。只要你在自己的网站里增加一个Meta标签,告诉360浏览器这个网址应该用哪个内核渲染,哪么360浏览器就会在读取到这个标签后,立即切换对应的内核。并将这个行为应用于这个二级域名下所有网址。
目前该功能已经在所有的360安全浏览器实现。我们也建议其它浏览器厂商一起支持这个实现。让这个控制标签成为行业标准。
在head标签中添加一行代码:
<html>
<head>
<meta name="renderer" content="webkit|ie-comp|ie-stand">
</head>
<body>
</body>
</html>
浏览器的兼容问题严重困扰了众多的软件工程师,不仅仅是前端开发,在此希望能够出台一个浏览器标准将所有的浏览器内核规范处理,开发工程师使用这个规范去开发,以减少这种“由于浏览器间客户流量竞争”而给开发者带来的工作量。
第三方支付过程中session失效问题的更多相关文章
- 支付宝PC端单笔支付同步回调session失效问题
一次调用支付宝PC场景下单笔支付之后同步回调遇到的session失效问题记录 问题描述: 调用支付宝接口:alipay.trade.page.pay,该接口请求参数中有两个返回地址需要设置,retur ...
- ASP.Net中Session失效的一种编程思路
在写一个客户的B/S结构应用程序时,突然发现一个技巧,不知道是否是MS的一个BUG,给相关的有研究的朋友原先考虑写一个检查Session的类,Session失效后,必须转向登陆页面,可每一个调用该类的 ...
- IE10中session失效取不到值的问题
在eworkflow工作流,ebiao报表,eform自定义表单产品升级到IE10的时候,系统登录后,总是会取不到session中的值. for j2ee版本和for dotnet版本都一样取不到值. ...
- 解决IIS设置多个工作进程中Session失效的问题
利用StateServer实现Session共享 session保存在专门的StateServer中,该种方式,性能损失比sql略好.比inproc据说有10%-15%的性能损失.怎么使用StateS ...
- iframe在浏览器中session失效问题
iis中右击项目属性http头 添加一个http头 X-UA-Compatible 自定义http头值 IE=EmulateIE7 这样设置后就可以了
- IE下IFrame引用跨域站点页面时,Session失效问题解决
问题场景:在一个应用(集团门户)的某个page中, 通过IFrame的方式嵌入另一个应用(集团实时监管系统)的某个页面. 当两个应用的domain 不一样时, 在被嵌入的页面中Session失效.(s ...
- 7.Android常用第三方支付
移动支付 用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付) app支付模块 常见的支付厂商-->常见的支付方式 支付宝 ...
- 第三方支付设计——账户体系
第三方支付架构设计之-帐户体系 一, 什么是第三方支付? 什么是第三方支付?相信很多人对这个名字很熟悉,不管是从各种媒体等都经常听到,可以说是耳熟能熟.但,如果非得给这个名词 ...
- Android常用第三方支付
移动支付 用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付) app支付模块 常见的支付厂商-->常见的支付方式 支付宝 ...
随机推荐
- Python基础4- 字符串
Python字符串是由数字.字母.下划线组成的一串字符,我们可以使用引号来创建字符串.如:str = 'Helloworld'在Python中没有char类型,单个字符也作为string使用; Pyt ...
- android6.0 适配的问题——activity销毁的问题
1.最近我去运行我们公司所开发的APP,发现出现很多问题,就是从前一个页面跳到另外一个页面后,前一个页面会被销毁. 正常来说,activity跳转过程是这样: A: 存在intent +setActi ...
- rJava包---R与Java的接口
1.安装 版本说明:Win10+R3.2.5+JKD1.7+eclipse-jee-mars-R-win32-x86_64 install.packages("rJava") 2. ...
- unity awake start 的区别
void Awake (){ } //初始化函数,在游戏开始时系统自动调用.一般用来创建变量之类的东西. void Start(){ } //初始化函数,在所有Awake函数运行完之后(一般是这样,但 ...
- BZOJ3515 : EvenPaths
首先拓扑排序,并将障碍点按拓扑序平均分成两半. 那么一条$0$到$1$的路径一定是形如: $0$->前一半点->后一半点->第一个后一半障碍点->后一半点->$1$. 对 ...
- Oracle 存储过程学习
转自:http://blog.chinaunix.net/uid-20495387-id-174394.html http://www.cnblogs.com/rootq/articles/11000 ...
- HDU3068最长回文 题解
题目大意: 求字符串的最长回文子串的长度. 思路: Manacher板题,Hash可能会T.要学习Manacher,可参考https://www.felix021.com/blog/read.php? ...
- 20161007 NOIP 模拟赛 T1 解题报告
排序 3.1 题意描述 众所周知,熟练掌握至少一种排序算法是参加NOIP的必备技能.常见的排序算法有冒泡 排序.归并排序.快速排序.奇偶排序.猴子排序.梳排序.鸡尾酒排序.臭皮匠排序等. 在这里,介绍 ...
- HighchartsJS创建环形带标识的图表实例
HighchartsJS 是一款功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库,目前最新版本库是Highcharts 4.1.9.另外,HighchartsJS还提供很多的插件和第三 ...
- [LintCode] Perfect Squares 完全平方数
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 1 ...