2

我有一个带有“loginStatus”字段的表。现在每次用户登录时,该值设置为 1,单击注销后,该值设置为 0。现在,当用户尝试登录时,检查该字段的值,如果为 0,则用户可以登录,如果为 1 则用户无法登录。现在,如果无论如何关闭浏览器,用户将无法使用该用户 ID 登录。因为那个字段的值仍然是1(他没有点击注销按钮所以它没有改变)。除非用户关闭浏览器,否则我的应用程序运行良好。

我知道这个问题可以用不同的方式解决,但我被要求这样做。现在的问题是我在 Java EE 方面不是那么专业,所以我正在寻找多种解释帮助。

我也有一个可能的解决方案,例如:创建一个数据库触发器以将 loginStatus 值更改为 0,这将在用户登录时触发,例如 15 分钟。现在我也不知道如何创建那种触发器将在特定时间后触发。

4

2 回答 2

2

如果您强制执行此要求,您可以自动使帐户过期,而无需运行任何作业。

代替简单的“开/关”标志,在表上设置一个日期/时间戳,该日期/时间戳设置为当前日期/时间。时不时地,当用户向服务器发出请求时,您会将此列更新为当前时间。

如果第二个会话尝试登录,该会话应检查表上的日期/时间戳,如果超过 15 分钟,则允许登录;否则它被阻止。

于 2012-04-13T01:49:41.563 回答
1

您可以创建一个定期运行并使旧会话过期的数据库作业。根据您使用的 Oracle 版本,您可以使用该DBMS_JOB软件包或更复杂的DBMS_SCHEDULER软件包。 DBMS_JOB是一个较旧的软件包,但对于像这样相对简单和孤立的任务,学习曲线较少。例如,如果您有一个存储过程UNLOCK_ACCOUNTS,该过程在执行时确定要解锁和解锁哪些帐户,您可以使用DBMS_JOB该过程每 15 分钟运行一次

DECLARE
  l_jobno INTEGER;
BEGIN
  dbms_job.submit( l_jobno,
                   'BEGIN unlock_accounts; END;',
                   sysdate + interval '15' minute,
                   'sysdate + interval ''15'' minute' );
  commit;
END;

当然,您也可以使用 Java 调度程序(Quartz是一种流行的调度程序)或DBMS_SCHEDULER包来做同样的事情。但是,这确实需要在某处有一个字段来存储登录时间戳,以便该UNLOCK_ACCOUNTS过程可以确定哪些登录发生在 15 分钟以上。

然而,一般来说,这整个架构是相当可疑的。很奇怪,您希望基于 Web 的应用程序(本质上是无状态的)拒绝登录,因为用户在某个较早的时间点打开了另一个浏览器。出于安全考虑,如果会话在一段时间内处于非活动状态,则将会话超时是相对常见的,但 15 分钟对于这类事情来说通常太短了——即使是银行网站也通常允许您比这更长的空闲时间。只要登录的时间间隔超过 15 分钟,这种方法似乎甚至不会阻止您同时从多个浏览器/计算机登录。

于 2012-04-12T20:47:43.660 回答