我想在 java 应用程序中创建一个计时器,用户可以根据该计时器在预定义的时间内登录该应用程序。一旦计时器值达到零,他/她将丢失其 session 对象并自动注销。
在 session 期间,如果用户在预定义的时间内执行某些任务,他的 session 时间将增加,否则他的时间将减少......一旦达到预定义的低时间,他将无法再次登录。
提出计时器对当前 session 产生影响的一些方法。
谢谢:)
最佳答案
免责声明:
我可以看到做类似事情的安全相关原因。我已经多次看到这种方法和各种应用程序,因此我可以理解为什么会提出这样的要求。当然,我认为一般来说实现这样的东西不是一个好主意,但是考虑到需求,我会分享我的想法并提供解决方案。
既然您在这里讨论 session ,我假设您位于网络域中。
IMO 有几种方法可以解决这个问题。
假设每个客户端都分配有一个
HttpSession
:在创建 session 时第一次调用时,将“当前时间”直接放入其中。然后创建一个过滤器,在第一个请求时执行上述逻辑,并在每次请求时将当前时间与第一个请求期间设置的时间进行比较。如果差异小于允许的时间 - 继续执行,否则强制注销,删除 session 和所有内容。我猜想此后用户将被迫重新连接。
示例:
假设允许用户登录 10 分钟
然后在过滤器中的任何后续请求中(伪代码):
doFilter() {
// if its a first request:
if(httpSessionIsCreatedInThisRequest() && noFirstLoginTimeOnSession()) {
httpSession.put("FIRST_LOGIN_TIME", getCurrentTime())
}
else { // for any subsequent request
currentTime = getCurrentTime()
if(currentTime - getFromSession("FIRST_LOGIN_TIME") < 10 mins) {
// you can proceed
}
else {
logout()
//do whatever You Need Here: logout, destroy the session
}
}
}
这个解决方案对于简单的情况来说已经足够好了,但是对于分布式应用程序来说还不够(它无法扩展)。此外,如果您有很多用户,那么为每个用户维护 HttpSession 是一项巨大的开销,因为 HttpSession-s 的可扩展性不够,并且您不希望进行 session 复制,因为它总是很痛苦:)
除了 HttpSession,您还可以通过 Cookie 实现相同的逻辑,但我怀疑它在安全性方面是否足够好。我提到这一点是因为我不知道您在这里有任何安全问题。
更具可扩展性的方法。不要使用 HttpSession,而是使用一些持久键值存储/东西,例如 Redis 服务器。将所有信息存储在那里。
根据具体的后端技术,您可以选择使用分配给数据库中每条记录的 TTL。您可能知道这一点,但为了答案的完整性:TTL(生存时间)意味着您指定服务器将自动删除(清除)对象而无需您干预的时间。因此,在这种情况下,您只需要检查该对象是否存在。这可以从许多服务器上完成,因为假设它们同步,在这种情况下它们不会共享有关用户的任何信息,因此可以更好地扩展。
现在您已经注意到所有这些解决方案根本不使用计时器。计时器可能会很昂贵,如果您对每个用户使用 Java util 计时器,它会在后台使用线程。因此,恕我直言,将线程数与用户数绑定(bind)是一个坏主意。
您可以利用像 Quartz(这是一个调度框架)这样的解决方案,但同样,如果您尝试为不同的用户创建不同的触发器,它将成为困惑且不可维护的代码。此外,如果你有太多的作业/触发器,Quartz 就会开始滞后,这不是你想要的。最重要的是,我真的不认为您应该在这种特殊情况下使用它。 Quartz是个好产品,请不要误会我的意思,我只是认为它不适合您这里的需求。
关于java - 代码中的计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35332090/