6

現在どのユーザーがリクエストを行っているかを知る必要がある監査証跡を作成しています。私の監査証跡は、監査が必要なものを受け取るためにActiveSupport::Notificationsを使用して作成されています。

私がやりたいのは、ActiveSupport :: Concernを使用して、監査のニーズに合わせてロジックをカプセル化することです。これにより、システム内の任意のモデルに監査を簡単に追加できます。

一般に、これは簡単に実行できます。私もしばらく前にそれについてブログを書きました。ただし、現在のユーザーがWebサーバーにリクエストを送信していることを確認する方法を理解するのに苦労しています。これにより、監査証跡で誰がどのような変更を行っているかをログに記録できます。

「モデルでcurrent_userを取得するにはどうすればよいですか」という質問がたくさんあることは知っていますが、モデルでそれを行うことについては質問していないので、より良い回答が得られることを期待しています。私の監査コードはインフラストラクチャに関連しているので、処理中の現在のリクエスト、または現在ログインしている/リクエストを行っている人を明確に教えてくれる何かを利用できる方法があることを望んでいます。

スレッドストレージを使用してcurrent_userをそこに配置するという「回答」をたくさん読みました。他の人が好まない多くの理由から、私はこの答えが好きではありません-スレッドストレージが安全であるという保証はありません。サーバーが同じスレッドを使用して複数のリクエストを処理する場合など、複数のリクエストにまたがってブリードする可能性があります。

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

アップデート

私は認証にdeviseを使用しています。これは、バックエンドでWardenを使用します。deviseは、を呼び出すことによってcurrent_userを取得しますrequest.env['warden'].authenticate(:scope => :user)(認証に「ユーザー」モデルを使用すると仮定します)。

request懸念事項または通知サブスクリプション内から現在のオブジェクトにアクセスする方法はありますか?.NETの時代に戻ると、電話をかけることができHttpContext.Current.Request、すべてが順調でした。Railsで同等のものは何ですか?

4

2 に答える 2

3

RailsActionController::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
于 2017-10-03T22:41:55.250 に答える
-1

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

HttpContext.Current.Request << これはスレッド ストレージを使用していると思います。私たちが見つけた他の解決策も、あるレベルまたは別のレベルのスレッドストレージになります。

コントローラーのリクエストから必要なものを引き出してパラメーターとして渡すか、スレッドストレージを使用しますが、これは本質的に危険です。通知などを行うために遅延ジョブを使用し始めたらどうなりますか?

于 2011-08-18T21:07:22.717 に答える