问题产行于公司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/cookie指的是当前访问的网站中会加载(嵌入)另外第三方的网站代码,例如促销广告,那么第三方网 站也会在访客的计算机上添加session/cookie,这种就是第三方session/cookie。 我的问题 在开发讯息...
最近由于一个项目,模块切换为ajax请求数据,当Session失效后,ajax请求后没有返回值,只有响应的html:<html>[removed]window.open(‘http://192.168.0.118:8080/welcomeAction/loginUI.do’,’_top’);...
【ASP.NET编程知识】iframe跨域与session失效问题的解决办法.docx
一同事求援:后台系统的登录成功了,但不能成功登进系统,仍然跳转到登录页,但同一套代码另一个环境却没有问题。 背景 经了解,他对同一个项目使用tomcat部署了两个环境,一个在开发服务器上,一个在他本机,两个...
环境: 前端 vue ip地址:192.168.1.205 ...搜索问题,发现跨域,服务器响应的setCookie浏览器无法保存,而且就算保存了域名不同也不能携带。 第一步: 后台添加过滤器,因为前后端分离,不可能每个方
主要给大家介绍了关于express如何解决ajax跨域访问session失效问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
主要给大家介绍了关于React如何解决fetch跨域请求时session失效问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
遇到了HTTP、HTTPS协议下session共享解决cookie失效的问题,这里提供一个临时解决办法。 实现原理:把session id设置到本地的cookie。 如下: 复制代码 代码如下: $currentSessionID = session_id(); session_id($...
今天搞的一个登录页面,被别的网站用iframe嵌进去后,死活无法登录(只在IE中存在这种情况)。 很明显,session无法被保存。但是直接在地址栏打开那个登录页面,一切都正常啊。真是奇怪啊。 在网上搜索了一下。发现...
在平台开发过程中,项目分为前台(frontend)www.xxx.com和后台(backend) yun.xxx.com两部分,绑定两个域名, 我们知道在没有绑定域名的时候前后台可以同步登录和退出,但是绑定域名后就失效了,原因是session的作用...
kisso 采用的是加密会话 cookie 机制实现单点登录 SSO 服务,具备“无状态”、“分散验证” ... 3、cookie 轻松实现分布式服务部署,单点登录跨域访问等问题,换成 session 需要处理 session 复制及各种问题实现困难。
n105 小结n第三部分 构建自定义控件 n第11章 构建自定义控件 n111 构建自定义控件概述 n1111 构建完全生成控件 n1112 构建组合控件 n1113 构建混合控件 n112 视图状态和控件状态 n1121 支持视图状态 n1122 支持控件...