2011-09-09 15 views
4

私は、一度に1つのアクティブなセッションしか持たないようにユーザーを制限する必要があるシナリオを持っています。 Mineはrails3アプリケーションであり、認証にdeviseを使用します。最新のユーザーセッションだけをアクティブにすることに興味があります。つまり、同じユーザー名に対して別のセッションがアクティブな間にユーザーがログインした場合、古いセッションを無効にして、最近のセッションを許可したいと考えています。ユーザーのセッションを取得して無効にする方法がありますか?Devise - 同じユーザーが別のブラウザ/マシンからログインした場合にユーザーセッションを無効にする

答えて

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別のインスタンスならば、現在のユーザーをログアウトします現在のユーザのログインします。これにより、任意の時点で1つのセッションだけがアクティブになります。

invalidate_simultaneous_user_sessionフィルタは、新たにログインしたユーザのトークンを更新するユーザログインアクションのためにスキップする必要があります。 Procを使ってコントローラー名とアクションに基づいてフィルターをスキップするのはうれしいです。既にdevdeのsessions_controllerをオーバーライドしている場合は、コントローラにskip_before_filter :check_simultaneous_user_sessionを追加すると、Proc!このことができます

・ホープ..レール4用の更新の工夫については

+0

に応じてコードを変更することができ、余分な '' '=' '' '' 'c.action_name = 'create''''でアクション名を割り当てずに比較します。私。だからそれは次のようになります: '' 'c.action_name == 'create'''' – ChrHansen

+0

@ChristianHansen残念です..それを修正しました! – dexter

+0

例を見る[ここ](https://gist.github.com/KieranP/9044432) –

関連する問題