如何使用相同的用户名防止多次登录?

时间:2016-12-13 07:29:20

标签: java postgresql

我正在开发一个适用于本地网络的应用程序。它在前端使用javafx 8,在后端使用Postgresql服务器。数据库存在于网络中的数据库服务器中。在服务器中,我们有一个表,用于存储用户详细信息,包括加密密码和用户ID。我们使用此表来验证希望登录的用户。

现在我们要阻止来自网络中多台计算机的同一用户ID登录到该应用程序。为此,我们尝试在存储用户详细信息的表中创建列loggedin。然后在列中存储布尔值true和false。因此,当用户成功通过身份验证后,我们会将true存储在loggedin列中的用户ID中。当用户注销时,我们会更新到表以在列中存储false

这个过程引发了一个新问题。如果在没有用户注销的情况下关闭应用程序,则用户将永远无法再次登录。此外,如果用户的计算机在没有用户注销的情况下关闭,则会得到相同的结果。如果由于任何原因重新启动服务器,那么所有登录的用户将永远无法再次登录。

我试图找到其他解决方案,但无法找到任何解决方案。如果任何人可以给我其他建议,将会非常有帮助。

3 个答案:

答案 0 :(得分:1)

我不同意你的结论。很明显,在应用程序启动时,没有人登录,因此您只需在应用程序启动时查询已登录的用户,并使用logged_in = false更新它们。

另一件事是心跳 - 每隔10分钟ping一次用户。如果没有答案,请强制注销,这会导致设置logged_in = false

答案 1 :(得分:1)

如果您只有服务器中的数据库,如注释中所述那么应用程序的服务器端没有启动。服务器端只包含数据库。 - Blip

我会使用数据库存储值lastQuery,该值应在某些操作期间更新。这应该在注销期间清除。如果您尝试使用此值登录,则要么拒绝(如果发生崩溃,则不承担任何注销的风险),或者询问您是否要清除之前的其他连接。

此值将为timestamp,以便知道最后一次操作完成的时间或使用“ping”表示您的连接(应用程序)仍处于活动状态(如果有一个或两个,则timestamp无效丢失ping(延迟时间戳大于ping之间的频率)。如果需要,这将用于在一段时间后自动注销用户。

没有更多信息就不能说更多

答案 2 :(得分:1)

如果您为每个用户提供自己的数据库角色,Postgres可以为您处理此问题(以及其余的身份验证过程):

#!/usr/bin/env perl
use strict;
use warnings;
use YAML;
use Data::Dumper;

#load yaml by reading files specified as args to stdin,
#or piped in. (Just like how you'd use 'sed')
my $config = Load ( do { local $/ ; <>} );

#output data structure for debug
print Dumper $config;

#use grep to filter the uri you don't want. 
@{$config -> {servers}} = grep { not $_ -> {uri} =~ m/demo.nginx2/ } @{$config -> {servers}};

#resultant data structure
print Dumper $config;
#output YAML to STDOUT
print Dump $config;

这还有许多其他好处,例如grantsrow-level policies的细粒度访问控制,以及authentication methods范围更广的访问权限。

如果这不是一个选项,最简单的方法可能是在登录时获得session-level advisory lock,即:

CREATE USER <username> PASSWORD '<password>' CONNECTION LIMIT 1

如果您已成功获取锁定,则会返回SELECT pg_try_advisory_lock(<userid>) ;如果其他人已锁定该true,则会返回false。获得后,锁定将在会话的剩余时间内保留,并在断开连接时自动释放。

请记住,您只是锁定一个任意数字,因此您需要确保没有其他进程因不相关的原因锁定相同的数字。管理此问题的常用方法是调用userid的双参数版本,并通过传入表的内部标识符将锁定范围限定到pg_try_advisory_lock()表:

users