感觉设置了cookie后session timeout没用

likeajin 2012-01-06 11:38:57
系统用cookie自动登录,用session控制是否超时,部分代码如下:

//web-config
……
<!-- session超时设置,单位为分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>


//登录方法:
public String loginAct(){
/**
* 查询数据,……
*/
//添加session
HttpServletRequest req=ServletActionContext.getRequest();
HttpServletResponse rsp=ServletActionContext.getResponse();
HttpSession session=req.getSession();
session.setAttribute("no","test");//值来自于查询后的数据
Cookie c;

c=new Cookie("no","test");//值来自于查询后的数据,保存帐号,下次不输入帐号,最多需要输入密码
c.setMaxAge(365*24*60*60);
c.setPath("/");
rsp.addCookie(c);

//判断是否需要添加cookie
if(rmb.equals("true")){//值来自于struts的action
c=new Cookie("pwd","test");//值来自于查询后的数据
c.setMaxAge(365*24*60*60);
c.setPath("/");
rsp.addCookie(c);
}
else{//否则删除cookie
Cookie[] cs=ServletActionContext.getRequest().getCookies();
if(cs!=null){
for(Cookie c:cs){
if(c.getName().equals("pwd")){
c.setMaxAge(0);
c.setPath("/");
rsp.addCookie(c);
}
}
}
}
……
}
//通过cookie登录的方法
public String loginByCookie(){
/**
* 查询数据,……
*/
//添加session
HttpServletRequest req=ServletActionContext.getRequest();
HttpSession session=req.getSession();
session.setAttribute("no","test");//值来自于查询后的数据
//不需要再次设置cookie
……
}
//安全退出的方法
public String logout(){
//清空session
delSession();
//删除cookies
delCookies();
……
}
//每个查询数据的方法都判断是否超时
protected boolean isLogout(){
HttpSession session=ServletActionContext.getRequest().getSession();
if(session==null||session.getAttribute("no")==null){
session=null;
result="logout";
return true;
}
else{
session=null;
return false;
}
}

问题描述:
1.如果登录时用了记住帐号,那么web-config中的session timeout貌似没用,测试时等多长时间isLogout都返回true。
2.如果没采用记住帐号,那么查询数据时不会进入到action中(action中调用islogout方法)。日志信息如下:

o.s.o.h.s.OpenSessionInViewFilter - Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter
o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'sessionFactory'
o.s.o.h.s.OpenSessionInViewFilter - Opening single Hibernate Session in OpenSessionInViewFilter
o.s.o.hibernate3.SessionFactoryUtils - Opening Hibernate Session
org.hibernate.impl.SessionImpl - opened session at timestamp: 5430564887359488
o.s.o.h.s.OpenSessionInViewFilter - Closing single Hibernate Session in OpenSessionInViewFilter
o.s.o.hibernate3.SessionFactoryUtils - Closing Hibernate Session


在线等急救,谢谢~~~~~~~~~,如果问题描述不够清楚请留言
...全文
536 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
MiceRice 2012-01-09
  • 打赏
  • 举报
回复
那么这个问题的复杂度提升一点点了,关系到:你是在哪里、如何检查会话超时的?

首先注意到:
HttpSession session=ServletActionContext.getRequest().getSession();
if (session==null) 这个判断本身,基本上肯定返回false,因为你getSession(),应用服务器就会为其初始化session对象。

所以这里能够发挥效用的检测是:
session.getAttribute("no")==null

但是,我发现你前面的很多地方,都会去设置会话的这个attribute:
session.setAttribute("no","test");
但是我不清楚你程序的完整逻辑是如何,但我认为这应该是主要问题。



建议调整如下:
◎ 判断用户是否已经登录的属性换一个名字,比如“logined”;
◎ 在验证用户名密码成功后,再session.setAttribute("logined", "YES");
◎ 超时判断用 session.getAttribute("logined") == null


jnhcd 2012-01-09
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分
likeajin 2012-01-09
  • 打赏
  • 举报
回复
问题是如果没记住帐号,那么在session超时的时候任何访问后台的操作都无法进入到对应action中。
如果记住了帐号,那么web-config中的session-timeout就不起作用,假设设置10分钟,逻辑上如果10分钟不做任何访问后台的操作那么session将超时,失效,但测试的时候却不是这样的……isLogout返回false。

ps:实在抱歉,1楼中的描述错了,是返回false……
MiceRice 2012-01-09
  • 打赏
  • 举报
回复
Nice done !

但我忍不住要提醒一句,你把用户的密码存在cookie里面,不是太合适。建议保存为:用户名+最后一次登录IP+最后一次登录时间+数据库中的用户序列号 的MD5 值这类比较有意思的组合内容。

原则就是:
◎ 跟时间相关(最后一次登录时间);
◎ 跟某个浏览器永远也得不到的数据相关(数据库中用户的序列号);
◎ 所有参数服务器端可验证;
那么你只要把这些数据从服务器端拿出来算一次,MD5值如果跟浏览器端的cookie一致,就可以了。
likeajin 2012-01-09
  • 打赏
  • 举报
回复
非常非常感谢ldh911耐心的指导,解决问题了,也达到我的目标了,OYE,原来真是过滤器没控制好。下面是解决方法:
关键在于过滤器和用户身份验证机制。我采用的机制:
1.用户没记住密码,在登录时删除用户cookie
2.用户记住密码,在登录时添加用户cookie
3.用户记住密码后,所有的登录通过cookie和数据库判断用户合法性,合法就进入首页,否则返回登录页
4.用户除开登录(包括一般登录和cookie登录)、登出操作外的其他任何操作都要判断其session。如果超时,那么提示用户登录超时并转向登录页面。

部分代码:
……内容有点多,有需求的或同样问题的可以+QQ 12619085,一起讨论,一起学习。

再次感谢ldh911
likeajin 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ldh911 的回复:]

依次回答:
1、这个本身并没有没问题;另外session超时是有事件的,可以用SessionListener去监听,但对你本帖中的需求应该无关;
2、这个问题让我不禁怀疑之前对你的表述又存在理解问题,我分两类解释:
a) 记录cookie后,用户将不再需要二次登录,用户随时访问都可直接按照登录后的状态进行处理;
b) 记录cookie后,用户第二次登录时,界面会自动带出用户名和密码,用户……
[/Quote]
估计就像你说的,现在想来好像是我的filter没控制好,我再试试

PS:15楼,貌似你跟错贴了
Ade子夜 2012-01-09
  • 打赏
  • 举报
回复
能否贴出来。你的解决方法
wuwohga 2012-01-09
  • 打赏
  • 举报
回复
纠结一天了,终于找到答案了,谢谢
MiceRice 2012-01-09
  • 打赏
  • 举报
回复
依次回答:
1、这个本身并没有没问题;另外session超时是有事件的,可以用SessionListener去监听,但对你本帖中的需求应该无关;
2、这个问题让我不禁怀疑之前对你的表述又存在理解问题,我分两类解释:
a) 记录cookie后,用户将不再需要二次登录,用户随时访问都可直接按照登录后的状态进行处理;
b) 记录cookie后,用户第二次登录时,界面会自动带出用户名和密码,用户可直接点击登录,很方便。
3、这个判断过程必须用filter来解决,写在后台的每个操作界面或Controller里面是不合理的。

继续细化第二个问题,我现在感觉你的要求应该是a,那么我按照a的方案来解释:
◎ 中间件是一定会有超时的,这个不需要做特殊处理,能超时是好事;
◎ 用于检查是否登录状态的filter,如果发现cookie中已经选择了记住登录状态,那么就要自动调用初始化会话信息的过程(初始化各类session中的其它属性);这样的话,整个程序结构就简单化了。
likeajin 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ldh911 的回复:]
那么这个问题的复杂度提升一点点了,关系到:你是在哪里、如何检查会话超时的?

首先注意到:
HttpSession session=ServletActionContext.getRequest().getSession();
if (session==null) 这个判断本身,基本上肯定返回false,因为你getSession(),应用服务器就会为其初始化session对象。

……
[/Quote]
其实我最纠结的是如果用户没保存密码,那么session超时后访问后台的任何操作都无法进入到action中,现在不知道是不是我理解错了,是不是本来就应该这样。如果是这样的话那有没有办法获取到session 超时的事件?
总而言之,我想实现的目标就是:
1.web-config中设置session最大有效时长。
2.用cookie保存用户部分信息,主要是保存帐号,只用登录一次。
3.在用户访问后台的任何操作中都加于判断,看该用户的session是否还有效,如果无效就提示登录超时,返回登录页面。
MiceRice 2012-01-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 likeajin 的回复:]
悲催啊,求专家啊,帮我看看吧
[/Quote]
又回头看了一遍你的主要问题,是说:
“如果登录时用了记住帐号,那么web-config中的session timeout貌似没用,测试时等多长时间isLogout都返回true”

从语义来判断,isLogout 就是为了判断是否已经退出登录是吧?返回true意味着已经退出登录。
那么你的描述并没有问题啊,符合程序设计意图啊?

你最后的这段程序返回true,也确实说明session没东西啊:
if(session==null||session.getAttribute("no")==null){
session=null;
result="logout";
return true;
}

你的问题究竟是啥?
likeajin 2012-01-08
  • 打赏
  • 举报
回复
悲催啊,求专家啊,帮我看看吧
MiceRice 2012-01-07
  • 打赏
  • 举报
回复
似乎Session不是这么清理的吧?应该是 session.invalidate(); 其它上面这一堆东西,都是不需要的。而且你即便把所有的attribute都删除掉了,其实session自己还健在。
likeajin 2012-01-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ldh911 的回复:]

似乎Session不是这么清理的吧?应该是 session.invalidate(); 其它上面这一堆东西,都是不需要的。而且你即便把所有的attribute都删除掉了,其实session自己还健在。
[/Quote]
我在delSession中添加了你说的那个方法,为什么还是不行?

private void delSession(){
HttpServletRequest req=ServletActionContext.getRequest();
HttpSession session=req.getSession();
if(session!=null){
if(session.getAttribute("JasperPrintList")!=null){
try{
List ujps=(List)session.getAttribute("JasperPrintList");
ujps.clear();
}
catch(Exception ex){}
session.removeAttribute("JasperPrintList");
}
session.removeAttribute("userNo");
session.removeAttribute("userDeptNo");
session.removeAttribute("userName");
session.invalidate();
}
}
likeajin 2012-01-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ldh911 的回复:]

似乎Session不是这么清理的吧?应该是 session.invalidate(); 其它上面这一堆东西,都是不需要的。而且你即便把所有的attribute都删除掉了,其实session自己还健在。
[/Quote]
嗯,谢谢你,我试试看
likeajin 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ldh911 的回复:]

楼主的delSession是什么样子的?
[/Quote]

private void delSession(){
HttpServletRequest req=ServletActionContext.getRequest();
HttpSession session=req.getSession();
if(session!=null){
if(session.getAttribute("JasperPrintList")!=null){
try{
List ujps=(List)session.getAttribute("JasperPrintList");
ujps.clear();
}
catch(Exception ex){}
session.removeAttribute("JasperPrintList");
}
session.removeAttribute("userNo");
session.removeAttribute("userDeptNo");
session.removeAttribute("userName");
session.setMaxInactiveInterval(0);//这个加不加暂时没发现有影响
}
}
MiceRice 2012-01-06
  • 打赏
  • 举报
回复
楼主的delSession是什么样子的?
likeajin 2012-01-06
  • 打赏
  • 举报
回复
来个人帮看看么,悲剧啊

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧