[英]How to prevent multiple logins using same username?
我正在開發可在本地網絡上運行的應用程序。 它在前端使用javafx 8,在后端使用Postgresql服務器。 該數據庫位於網絡中的數據庫服務器中。 在服務器中,我們有一個表,用於存儲用戶詳細信息,包括加密的密碼和用戶ID。 我們使用此表來驗證希望登錄的用戶。
現在,我們要阻止來自網絡中多台計算機的同一用戶ID登錄到該應用程序。 為此,我們試圖在存儲用戶詳細信息的表中創建一個loggedin
欄。 然后在該列中存儲布爾值true和false。 因此,當用戶成功通過身份驗證后,我們loggedin
與用戶ID對應的true
存儲在loggedin
欄中。 當用戶注銷時,我們將更新到表以在列中存儲false
。
這個過程引起了一個新的問題。 如果在沒有用戶注銷的情況下關閉了應用程序,則用戶將永遠無法再次登錄。 同樣,如果在未注銷用戶的情況下關閉用戶計算機,也會得到相同的結果。 而且,如果由於某種原因重新啟動了服務器,則所有已登錄的用戶將永遠無法再次登錄。
我試圖找到其他解決方案,但找不到任何解決方案。 如果有人可以給我其他建議,那將非常有幫助。
我不同意你的結論。 顯然,在應用程序啟動時,沒有人登錄,因此您可以簡單地在應用程序啟動時查詢已登錄的用戶,並使用logged_in = false
對其進行更新。
另一件事是心跳-每10分鍾ping用戶一次。 如果沒有答案,請強制注銷,這將導致設置logged_in = false
。
如果您只有服務器上的數據庫,如注釋中所述, 那么就沒有應用程序的服務器端可以啟動。 服務器端僅包含數據庫。 –斑點
我將使用數據庫存儲值lastQuery
,該值應在某些操作中進行更新。 這應該在注銷過程中清除。 如果您嘗試使用此值登錄,則您要么拒絕(如果發生崩潰,則有風險,因此不注銷),或者詢問您是否要清除其他先前的連接。
該值將是一個timestamp
用於了解何時執行了最后一次操作或使用“ ping”來表明您的連接(應用程序)仍處於活動狀態(如果錯過了一兩個ping,則使timestamp
無效( timestamp
延遲大於頻率)在兩次ping之間),如果需要,可以在一段時間后自動注銷用戶。
沒有更多信息就不能說更多
如果您為每個用戶賦予自己的數據庫角色,則Postgres可以為您處理此任務(以及其余的身份驗證過程):
CREATE USER <username> PASSWORD '<password>' CONNECTION LIMIT 1
這還有許多其他好處,例如通過授權和行級策略進行細粒度的訪問控制,以及訪問范圍更廣的身份驗證方法 。
如果這不是一個選擇,則最簡單的方法可能是在登錄時獲取會話級咨詢鎖 ,即:
SELECT pg_try_advisory_lock(<userid>)
如果您已成功獲取該鎖,則將返回true
如果該userid
的鎖已被其他人持有,則將返回false
。 一旦獲得,該鎖將在您的其余會話中保留,並在斷開連接時自動釋放。
請記住,您只是鎖定一個任意數字,因此您需要確保沒有其他進程出於不相關的原因鎖定相同的數字。 管理此問題的常用方法是調用pg_try_advisory_lock()
的兩個參數的版本,並通過傳入表的內部標識符來將鎖定范圍鎖定到users
表:
SELECT pg_try_advisory_lock('users'::regclass::int, <userid>)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.