2013-10-20 136 views
1

我试图阻止多个记录我的应用程序,对此我使用这种方法:不要允许用户多次登录

在我第一次用户登录保存在一个会话的用户,第二次用户尝试再次登录,我首先检查会话,如果会话已经有相同的用户,我不允许用户再次登录。

此方法在同一浏览器中工作良好,但是如果我尝试再次登录同一用户从另一个浏览器,它允许多个登录,因为会话中没有任何内容。

如果我尝试从其他计算机登录,则会发生同样的问题。

请建议。 感谢

这里是我有

  User user = (User) rdbHelper.getAuthentication(userid, password); 
    if(user!=null) 
    { 
     session=getThreadLocalRequest().getSession(true); 
     User loggedInUser = (User) session.getAttribute("user"); 

     if(user.getId() == loggedInUser.getId()){ 
     user.setId(0); // making user null and stopping user to login 
     }else{ 
     session=getThreadLocalRequest().getSession(true); 
     session.setAttribute("user", user); // allow user to sing in 
     } 
+0

这不能用仅仅一个会话来完成,但是你需要在数据库中存储IP地址,并且基于你需要检查 –

回答

2

下面是步骤,你可以试试要实现这一点:

  • 用户登录后立即将其IP地址,他的名字和/或一些随机生成的令牌存储在数据库中的某个表中。
  • 当用户注销时,清除表中以前存储的值。
  • 在登录过程中,检查该表以查看表中是否存在用户信息,如果信息可用,则表示用户已从其他计算机,浏览器等登录并拒绝登录访问。
  • 如果信息不可用,则允许用户登录。

但是,当然,这也不是傻瓜证明,根据你的需要,你可能需要添加adiitional列等

还有一些在这种方法需要被处理,一个一些缺点案例是:

1)如果用户的PC关闭或用户不打扰注销会发生什么?在这种情况下,用户将被剥夺访问权限。

在这种情况下,应该有一些作业在特定的时间间隔进行清理过程。您可能需要在查找表中添加“Timestamp”列,该作业的主要工作是将时间戳与某些预定义的超时值(比如10分钟)进行比较,并删除所有这些行。

因此,用户可以登录没有问题。

+0

谢谢,但如果用户计算机意外关闭,用户没有登出自己,用这种方法,我认为他将永远无法再次登录 – junaidp

+0

@junaidp,我编辑:)在这种情况下,应该有一些工作在特定的时间间隔内清理表格,就像会话超时一样。 –

+0

谢谢:)。这种方法很好,但是你的意思是说,每隔10分钟就会有一次调用数据库。即使用户电脑运行正常,他正在处理我的应用程序。在这种情况下,这个工作正在运行在指定的时间间隔将在10分钟后进入数据库,并删除所有内容即使用户正在顺利使用应用程序(无PC挂起或任何其他),但数据库表现在清除了,所以...其他用户可以登录..我是对的吗? – junaidp

0

当用户通过Web浏览器做个像正常的会话登录,然后在数据库中你的状态,他们已登录。当他们尝试再次登录您检查用户的数据库,如果他们登录,不要让他们在新的页面上。

当他们注销你破坏了会议,但你还需要将数据库设置为说,他们还没有登录,这将阻止人们记录从不同的浏览器

+0

谢谢,但是如果用户计算机意外关闭或者用户关闭浏览器而没有输出日志用这种方法,我认为他永远不能再次登录 – junaidp

+0

你为时间添加一个会话变量。这是我如何做到的。如果他们在访问页面时设置了时间变量,那么检查时间并与时间比较,如果超过x分钟,则删除用户名的会话变量,这将允许他们重新登录 – NoLiver92

+0

但该事物只应检查IF x Minutes是不活动的,否则它会清除session/db(即使用户仍在使用我的应用程序).​​.另一个用户将能够登录,所以多次登录问题将再次出现 – junaidp

0

您可以在用户表中添加一个字段名称为“IsLoggedIn”的额外字段作为位字段,并将其设置为true,直到用户注销。一旦用户注销,将其设置为false。这也需要在会话到期时间完成。一旦会话过期,该字段应该使用触发器或通过SP呼叫自动设置为false。 当试图从不同的浏览器或计算机登录时,它应该检查“IsLoggedIn”字段,如果它已经是真的,如果它不是,让用户登录。

+0

谢谢,你能给我一个想法如何在会话超时时调用分贝,我将如何知道在代码中会话超时。 – junaidp

0

我们有我们的工作项目类似的情况,我们采取的方法是:

  1. 生成令牌每当用户登录,并将其存储在会话和数据库此用户。
  2. 向服务器发送每个请求后,请验证该令牌,以确保他处于有效会话中,并且在超时后他不再回来。 (任何时间间隔超过15分钟的请求,我们使令牌无效)
  3. 如果用户尝试再次登录(例如,从不同的浏览器或未注销),我们可以看到该令牌仍然存在该用户的数据库,如果他想“杀死”旧会话,我们会向用户显示一条警告消息。这样,即使计算机崩溃或忘记注销,他也可以决定终止旧会话并继续新会话。或者他可以取消创建新的令牌以继续在旧会话中工作。
  4. Ofcourse,如果用户点击“注销”,我们清除令牌
+0

你能否用我的这句话,你是怎么做到的:即使电脑崩溃或忘记注销,他也可以决定杀掉旧的会话并继续新的会话 – junaidp

0

尝试在servlet上下文中存储数据。当用户登录时

context = getServletContext(); 
List<string> logins = context.getAttribute("logins"); 
logins.add(username); 

检查登录可以这样工作。

context = getServletContext(); 
List<string> logins = context.getAttribute("logins"); 
if (!logins.contains(username)) { 
    login(); 
} else { 
    deny(); 
} 

使用servletContextListener在应用程序启动时创建列表。

我会使用HttpSessionListener来管理列表。会话结束后,检查它是否已登录,并从列表中删除登录名。