我有一個功能驗證,ACL和會話管理系統爲我的在線軟件應用程序。由於這是每個用戶帳戶的付費服務,因此我需要確保用戶帳戶不能與PayPal管理業務帳戶的方式在員工之間共享。防止多臺設備同時登錄到一個用戶帳戶
我的努力是找到一種方法來實現這樣的功能,勝任的技術用戶無法通過修改Javascript或使用客戶端代理來規避。
目前,每個公司帳戶都在我的服務器上有一個「會話」表,由session_id (PK), session_user, session_data, client_ip, timestamp_created
和timestamp_updated
列組成。無論用戶何時登錄,session_user
列都將使用其登錄名進行更新。如果其他人在另一臺計算機上登錄該帳戶,以前訪問過的帳戶將會將session_user列設置爲NULL
。結果是,對於session_user
,沒有兩行應該具有相同的值。可能值得注意的是,客戶沒有對其數據庫的管理訪問權限。
客戶端應用程序每5秒對定時器運行一個Javascript函數,該函數執行對Zend控制器的AJAX調用。該控制器通過使用Zend_Session::getId();
的DB查詢來檢查session_user
列中的活動會話。此方法echo
的與success
一個JSON編碼的響應設定爲TRUE
如果session_id
在數據庫中具有相關聯的session_user
,或FALSE
如果在session_user
列中沒有值。如果該方法返回FALSE
,則Javascript函數繼續提醒用戶另一臺計算機已登錄其帳戶,然後將其重定向到登錄頁面。
這種方法的問題在於,任何有Chrome瀏覽器或Mozilla FireBug經驗的人都可以刪除執行AJAX調用的Javascript,並繼續在衆多機器上使用該應用程序。更糟糕的是,這種簡單的方法只是脆弱性的開始。
我有一種感覺,我需要查看Zend的插件架構,可能在preDispatch()
期間執行檢查以確保當前session_id
的值已在相應的session_user
表中設置。這個檢查對我目前的結構是免費的,因爲我覺得我的大部分用戶本身並不熟悉基本的「黑客行爲」,並且會發現阻止賬戶分享。如果此服務器端檢查失敗(如請求資源時發生的那樣),則可能會拋出錯誤,並且所請求的數據不會推送到前端(例如查看產品的數據)。
這種方法看起來是否會起作用,還是有更好的方法來實現這種功能?我讀過一堆SO帖子,這些帖子讓人討厭關於在最終用戶上如此繁瑣是否是個好主意的爭論。我們已經決定,由於收入主要基於購買額外用戶帳戶的公司帳戶,因此需要防止任何類型的帳戶分享。防止用戶使用現有會話登錄帳戶是我想要避免的。信不信由你,我寧願讓用戶因被其他設備登錄而從他們的活動會話中啓動而感到惱火,因爲我認爲這將鼓勵購買額外的用戶許可證。
請隨時詢問您是否需要任何其他信息,或者需要澄清我在帖子中描述的任何內容。
謝謝@Hope的建議,但是這種方法不適用於我的軟件,因爲它是一個託管的SaaS應用程序 - 我很抱歉沒有清楚地解釋這一點。由於我們針對的是小型企業,因此我認爲所有計算機都將位於同一臺路由器之後,因此很可能會NAT。爲了防止來自多個地理位置分散的位置(即使用來自ISP的不同IP地址)的併發登錄,您的解決方案將非常有效! +1瞭解和幫助。 – 2012-07-16 16:53:50
可能的警告:此實施可能會對擁有大量IP地址的企業網絡或大學中的客戶端產生不利影響。負載均衡器可能會導致客戶端數據包在併發請求中使用不同的IP地址發送出去。 – 2012-07-16 16:58:40