近来正在解决一个单点登录的遗留bug,用户反映的问题有两个:
1.在某页面长时间无操作,导致session过期,用户需要重新登录
2.关闭IE后session无法马上过期,导致用户无法继续登录
?
解决方案如下:
1. 对于第一个的解决方案是增加session的过期时间,目前是一小时.
2.第一个的解决方案导致第二个问题很严重,关闭IE后session不过期,用户长时间无法登录.在google,百度一大堆之后发现网上的方法没有效果.后来测试发现
event.clientX>document.body.clientWidth
这个条件有时候在关闭IE时是不成立的,现将该条件删除。
?
完整代码如下:
(function(){
window.onbeforeunload = function(){?
if (event.clientY<0 || event.altKey){
var confirmResult = window.confirm("关闭页面后需要重新登录.确定关闭吗?");
if(confirmResult){
// 通知销毁session,保证用户登录能成功
}else{
return "请点击取消按钮";
}
}
}?
?
})();
?
本想用项目里的confirm弹出框,但是无法阻塞关闭IE的线程,IE仍然会关闭,所以只好用IE自带的confirm弹窗来处理:
点击"确定",通知后台销毁session,流程结束;
点击“取消”,这时会弹出IE关闭的提示框,也有“确定”和“取消”两个按钮,不过这两个按钮的点击事件无法获取。再点击“取消”,提示框消失,流程结束;如果点“确定”,浏览器关闭,但是没有通知后台销毁session,如果此时session还没有过期,用户仍然无法登录。看来前台是没有更好的办法,只能后台解决。
?
后台解决方案:
目前系统对于用户会保存在两个地方:session和一个静态的Map<userId, user>中。
新建一个Map<userId, HttpSession>用来存用户和sessoin的对应关系。下面这个表格应该能说明问题:
?
| Session | UserMap | 处理结果 |
| 存在用户 | 不存在登录用户 |
销毁session,SessionMap删除相应的session,重新获取session, user加入session和UserMap中,session加入SessionMap中,登录成功,进入首页 |
| 存在用户 | 存在登录用户 | if(用户与登录用户 name 相同)???? 相同session,不作处理 if(用户与登录用户 name 不相同) 不同session,已在别处登录 |
| 不存在用户 | 不存在登录用户 | 登录用户加入session和UserMap中,session加入SessionMap中,登录成功,进入首页 |
| 不存在用户 | 存在登录用户 |
从SessionMap获取旧session后,销毁且从SessionMap中删除, 登录用户加入新session和UserMap中,新session加入SessionMap中 |
?
其实个人感觉只有这个后台,没有前台也能解决用户登录的问题。