如何防止用户重复登陆??

sky_1989 2008-06-07 01:54:19
用session监听器的话
一般都会存在一个问题:如果用户没有正常退出系统(如直接点浏览器右上角的关闭),那么他接下来继续登陆的时候,因为Session没有过期等问题,会被拒绝继续登陆系统,只能等待Session过期后才能登陆。
我想的实现的功能:
第二次登陆时会把第一次的登陆注销掉,第一次登陆将会类似于MSN弹出:您的帐号已在别处被登陆,您被强迫下线的提示信息。
这要如何实现啊??
哪位高手给个实例
...全文
1822 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
I威尔KOU 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

问题的关键还是在如何判断用户是否在线!!

用户登录后,将用户的一个online 属性更新为true;并记录其sessionId

第二次登陆时,则更新sessionId

第一个再次访问时,虽然session没有过期,但检测后发现其sessionId 与用户的sessionId 不等,则强制退出。
[/Quote]
sessionId 应该记录在哪里呢?
第一个用户登陆后,将其online 属性更新为true; 第二次登陆时就可以从数据库中取得用户的online信息,发现值为true,就可以提示说此用户已经登陆了,既然登陆了还要提示强制退出,还不如不让他登陆就提示无法登陆或者把已登录的用户踢掉,都可以,sessionId 岂不是多余的?
hepeng_8 2012-04-17
  • 打赏
  • 举报
回复
问题的关键还是在如何判断用户是否在线!!

用户登录后,将用户的一个online 属性更新为true;并记录其sessionId

第二次登陆时,则更新sessionId

第一个再次访问时,虽然session没有过期,但检测后发现其sessionId 与用户的sessionId 不等,则强制退出。

太牛逼了
zhangyu093305 2012-04-06
  • 打赏
  • 举报
回复
学习了。马上试试看看!!!
fuyou001 2008-06-09
  • 打赏
  • 举报
回复
学习了...
glx1857 2008-06-09
  • 打赏
  • 举报
回复
同意老紫竹的方法
sunyujia 2008-06-09
  • 打赏
  • 举报
回复
上面各位的想法都有看,
1.cooKie有可能不开的
2.把session放ServletContext会不会导致内存泄露啊,这个待验证
3.客户端一定不能靠ajax搞大量并发服务器承受不了
4.靠javascript监控页面关闭事件是不可靠的,遨游下默认就不好使


同一账号可以登录两次的方案:
我没有这方面需求所以也不太了解常规是如果干的,但是有一点你要清楚,就是msn是c/s程序他的工作方式和http协议是不同的,http是无状态的,客户端必须主动请求服务器才行,也就是说如果B提掉A,系统要提示A的话需要靠异步job不断的请求服务器,这样压力太大了.

下面我想出一个比较可行的方案:
A先上线B后上线,这时系统不要提示A已经被提掉了,而是在A再次访问其他页面的时候(这时候是要走过滤器的),过滤器判断出A已经被T了,这时候在提示A,也就是说让A触发这个被T的消息.
如何知道A已经失效用4楼的方法就可以了.

同一账号不可以登录两次的方案:
老实说我觉得除非客户端ajax并发否则没有太精准的办法.

sky_1989 2008-06-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sunyujia 的回复:]
我见过的一个比较另类的方法你可以参考下,或许会有启示

利用SQLServer的全局临时表防止用户重复登录

百度上面的关键字
[/Quote]
既然是另类的话
有没有什么主流的方法??
如果同一帐号不可登陆2次要怎么办?
session的话,如果用户非法退出,就要等session失效第二次登陆才可以
吴青峰 2008-06-09
  • 打赏
  • 举报
回复
尝试用cooKie看看;
因为它有周期,
所以因该比较好
yami251139 2008-06-08
  • 打赏
  • 举报
回复
为什么要用临时表?
第二次登陆判断下,如果已经存在,就获得那个用户,然后清空下他之前的操作
goldlive_8888 2008-06-08
  • 打赏
  • 举报
回复
同意老紫竹的方法
1、用户每次操作时都要比对一下自己的sessionid与数据库中的sessionid是否一致。注意,注销时一定要清空sessionid字段。
2、如果是管理系统,可以在主控制页中做一个javascript,间隔一段时间去比对一下。
Brokenfango 2008-06-08
  • 打赏
  • 举报
回复
UP
limon758 2008-06-08
  • 打赏
  • 举报
回复
后登陆的用户会把先登陆的用户踢下线

具体实现:sessionCheck:

package test;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionMapping;

public class sessionCheck
{

private static sessionCheck sessioncheck;
public sessionCheck(HttpServlet servlet)
{
}
public static sessionCheck getInstance(HttpServlet servlet)
{
if (sessioncheck==null)
{
sessioncheck=new sessionCheck(servlet);
}
return sessioncheck;
}
public void setSession(String userName,HttpServlet servlet,HttpSession session,ActionMapping mapping)
{
final ServletContext sc = servlet.getServletContext();//取得容器,容器中根据用户唯一标识userID存放session
System.out.println(sc);
System.out.println(session);
if (sc.getAttribute(userName) != null)
{
// 第二次登陆后第一次无效
((HttpSession) sc.getAttribute(userName)).invalidate();// 清除第一次登陆的session
System.out.println(session);
}
sc.setAttribute(userName, session);//放入当前最新session
mapping.findForward("sessionDestroy") ;
}

}

UserLoginForm:

sessionCheck.getInstance(this.getServlet()).setSession(userName, servlet, session, mapping);

jsp:

<body ="sessionDestroy()">

< language="java" type="text/java">
sessionDestroy()
{
alert("连接超时,或帐号已在别处登陆,请查证后重新登陆");
location.href = "UserLogin.jsp" ;
}
</>
这样在两台电脑上后登陆的人用户就会把先登陆的给踢掉,但是暂时还没实现在同一台电脑上后登陆的用户把先登陆的踢掉的功能

上面是在后台实现的,如果要在JSP中做,直接appliction.getAttribute(userId),appliction.setAttribute(userId, session)就行
sunyujia 2008-06-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yami251139 的回复:]
为什么要用临时表?
第二次登陆判断下,如果已经存在,就获得那个用户,然后清空下他之前的操作
[/Quote]

* 在connection断开连接后,全局临时表会被SQL Server自动回收

* 如发生断电之类的意外,全局临时表虽然还存在于tempdb中,但是已经失去活性

呵呵,比较另类的方法。
lydiablo 2008-06-08
  • 打赏
  • 举报
回复
大家给的代码都满有参考价值的。学习了!!
KKK2007 2008-06-08
  • 打赏
  • 举报
回复
token防止重复提交就可以了
yooooyiiiiiiiiii 2008-06-08
  • 打赏
  • 举报
回复
问题的关键还是在如何判断用户是否在线.
-同意。
其实你可以看看一些比较好的源码,看看人家是如何做的。不必自己再讨论了。
realcbb 2008-06-08
  • 打赏
  • 举报
回复
因为判断用户是否在线比较困难,所以选择将先前用户踢下线的方案。
我的解决思路是这样的,具体的细节楼主自己思考:
1.servlet初始化时在servletContext里面加一个HashMap,用来保存sessionId和用户名。
2.当用户登陆时首先检查HashMap中是否已经存在这个用户名的sessionId,如果有则销毁此session,并从HashMap中删除相应的信息;如果没有则把sessionId和用户名保存在HashMap中,并给session添加一个flag。
3.用户主动下线时,销毁session,并从HashMap中删除相应的信息。
4.过滤器中对除注册登陆之外的每个请求判断session中是否有flag,如果没有则提示未登陆,返回登陆页面。

如果需要即时性,可以将页面用框架来做,用ajax每隔1秒去检测自己的sessionId是否仍在HashMap中,如果不存在,弹出提示“此帐号在别处登陆,您已被强制下线”。不过这样会增加服务器负担,不推荐。

老紫竹 2008-06-07
  • 打赏
  • 举报
回复
问题的关键还是在如何判断用户是否在线!!

用户登录后,将用户的一个online 属性更新为true;并记录其sessionId

第二次登陆时,则更新sessionId

第一个再次访问时,虽然session没有过期,但检测后发现其sessionId 与用户的sessionId 不等,则强制退出。

sagezk 2008-06-07
  • 打赏
  • 举报
回复
1楼2楼结合一下,使用 HttpSessionListener 在 Session 创建时将用户 ID 写入临时表,销毁时将 ID 从临时表中删除,第二次登录根据临时表查询结果判断是否弹出异地已登录提示,并将第二次尝试异地登录信息写入临时表,第三次登录如果用户的ID和密码经验证正确就删除临时表中记录作正常登录处理。另外临时表的主键可以使用 SessionID。
sunyujia 2008-06-07
  • 打赏
  • 举报
回复
我见过的一个比较另类的方法你可以参考下,或许会有启示

利用SQLServer的全局临时表防止用户重复登录

百度上面的关键字
加载更多回复(1)

81,092

社区成员

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

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