2011-06-29 10 views
5

私は現在、どのユーザーがリクエストを行っているかを知る必要がある監査証跡を作成しています。私の監査証跡は、ActiveSupport :: Notificationsを使って構築され、それを監査する必要があります。Rails通知からcurrent_userにアクセスする方法は?

私がしたいのは、ActiveSupport :: Concernを使用して自分の監査ニーズのロジックをカプセル化し、システムのどのモデルにも簡単に監査を追加できるようにすることです。

一般的に、これは簡単です。私はさらにblogged about it a while backです。しかし、現在のユーザーにWebサーバーへのリクエストを行う方法を理解するのは難しいので、誰が自分の監査証跡に変更を加えるのかを記録できます。

「私のモデルにcurrent_userを取得するにはどうすればよいですか」という疑問があることは知っていますが、モデルでそれを行うことを求めているわけではないので、より良い回答が得られることを願っています。私の監査コードはインフラストラクチャに関連しているので、現在処理中のリクエストや、現在ログインしている/要求していることを明確に示す何らかの方法があることを期待しています。

私は、スレッドストレージを使用してそこにcurrent_userを置くと言う、多くの "答え"を読んだことがあります。私は他の人がそうしない理由の多くに対してこの答えが嫌いです - スレッドストレージが安全であるという保証はありません。サーバが同じスレッドを複数のリクエストを処理するために同じスレッドを使用する場合、複数のリクエストにまたがって出現する可能性があります。

...私のモデルからcurrent_userにアクセスするのではなく、ActiveSupport :: ConcernまたはActiveSupport :: Notificationsイベントサブスクリプションを使用すると、現在のユーザーが誰であるかを知る良いオプションがありますか?

更新

私はバックエンドでウォーデンを使用する、認証のために考案し使用しています。私はrequest.env['warden'].authenticate(:scope => :user)を呼び出すことによってcurrent_userを取得します(私は認証のために "User"モデルを使用します)。

私の懸念や通知のサブスクリプションから現在のrequestオブジェクトにアクセスする方法はありますか?私の.NETの時代に戻って、HttpContext.Current.Requestと呼ぶことができたと思います。 Railsに相当するものは何ですか?

+0

感謝。 :)それをしようとしていたし、あなたがそれを世話していたのを見た! –

+0

この解決策をお探しですか?あなたがした場合、それについて書いてください。ありがとう。 – Shreyas

答えて

-1

あなたはすでに答えを持っています。あなたがやっていることは、人々がモデルのリクエストにアクセスしているときと同じです。 current_userは、あなたのApplicationControllerで定義された単なるメソッドです。あなたがそれを継承するコントローラや他のクラスにないときは、そのメソッドにアクセスすることはできません。

HttpContext.Current.Request < <これはスレッドストレージを使用することが多いと思います。私たちが見つけた他のソリューションは、あるレベルまたは別のスレッドストレージになります。

コントローラーの要求から必要なものを取り出し、パラメーターとして渡すか、スレッドストレージを使用するかのどちらかですが、これは本質的に危険です。遅れた仕事を使って通知などをするとどうなりますか?

+0

これは、レールの明示的な機能を使用して、スレッドローカルストレージを必要とせずに、 'append_info_to_payload'を使用して可能です – cluesque

0

RailsのActionController::Instrumentationには、append_info_to_payloadを使用する明示的なサポートがあります。

があなたのApplicationControllerにメソッドを追加します。

def append_info_to_payload(payload) 
    super 
    payload[:current_user_id] = current_user.try(&:id) 
end 

今、あなたの観測者がコールバックされたときに、情報がevent.payloadになります:リンクの修正のための

ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args| 
    event = ActiveSupport::Notifications::Event.new(*args) 
    current_user_id = event.payload[:current_user_id] 
    # do something interesting with current_user_id here 
end 
関連する問題