我正在开发一个适用于本地网络的应用程序。它在前端使用javafx 8,在后端使用Postgresql服务器。数据库存在于网络中的数据库服务器中。在服务器中,我们有一个表,用于存储用户详细信息,包括加密密码和用户ID。我们使用此表来验证希望登录的用户。
现在我们要阻止来自网络中多台计算机的同一用户ID登录到该应用程序。为此,我们尝试在存储用户详细信息的表中创建列loggedin
。然后在列中存储布尔值true和false。因此,当用户成功通过身份验证后,我们会将true
存储在loggedin
列中的用户ID中。当用户注销时,我们会更新到表以在列中存储false
。
这个过程引发了一个新问题。如果在没有用户注销的情况下关闭应用程序,则用户将永远无法再次登录。此外,如果用户的计算机在没有用户注销的情况下关闭,则会得到相同的结果。如果由于任何原因重新启动服务器,那么所有登录的用户将永远无法再次登录。
我试图找到其他解决方案,但无法找到任何解决方案。如果任何人可以给我其他建议,将会非常有帮助。
答案 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;
这还有许多其他好处,例如grants和row-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