2011-09-09 38 views
4

我有一個場景,我需要限制用戶一次只有一個活動會話。 Mine是一個rails3應用程序,並使用設計進行身份驗證。我只想保持最新的用戶會話處於活動狀態。即如果一個用戶登錄,而另一個會話對同一個用戶名有效,我想停用舊的會話並允許最近的一個。在設計中,是否有辦法獲取用戶會話並使其失效?設計 - 如果同一用戶從不同的瀏覽器/計算機登錄,則會失效用戶會話

回答

13

您可以通過在數據庫中存儲特定於該用戶的唯一令牌來跟蹤特定用戶的會話。

創建遷移以添加用於存儲令牌的字段。我假設設計模型是用戶。

class AddSignInTokenToUsers < ActiveRecord::Migration 
    def change 
    add_column :users, :current_sign_in_token, :string 
    end 
end 

下面的代碼添加到application_controller.rb

class ApplicationController < ActionController::Base 
    before_filter :invalidate_simultaneous_user_session, :unless => Proc.new {|c| c.controller_name == 'sessions' and c.action_name == 'create' } 

    def invalidate_simultaneous_user_session 
    sign_out_and_redirect(current_user) if current_user && session[:sign_in_token] != current_user.current_sign_in_token 
    end 

    def sign_in(resource_or_scope, *args) 
    super 
    token = Devise.friendly_token 
    current_user.update_attribute :current_sign_in_token, token 
    session[:sign_in_token] = token 
    end 
end 

sign_in(resource_or_scope, *args)是有一項掛鉤將被調用每次用戶登錄。如果另一個實例

invalidate_simultaneous_user_session將註銷當前用戶的當前用戶登錄。這將確保只有一個會話在任何時刻都處於活動狀態。

invalidate_simultaneous_user_session過濾器應該跳過用戶登錄操作來更新新登錄的用戶令牌。我不喜歡使用Proc根據控制器名稱和操作跳過過濾器。如果您已經覆蓋了設備的sessions_controller,那麼在該控制器中包含skip_before_filter :check_simultaneous_user_session,您可以擺脫Proc!

希望這有助於..

+0

我認爲你需要更改代碼的額外'''='''在'''c.action_name ='create''''中不分配,但比較操作名稱。即所以它變成:'''c.action_name =='create'''' – ChrHansen

+0

@ChristianHansen哎呀..對不起..糾正! – dexter

+0

看一個例子[here](https://gist.github.com/KieranP/9044432) –

相關問題