9

Active Resource は、クラス レベルで設定された HTTP 認証を利用できます。例えば:

class Resource < ActiveResource::Base
end

Resource.user = 'user'
Resource.password = 'password'

また

Resource.site = "http://user:password@site.com/"

しかし、ログインしているユーザーに基づいて異なる HTTP 認証を使用するとどうなるでしょうか? Resource.user と Resource.password を変更すると、あるスレッドからのリクエストが別のスレッドで同時に実行されているユーザーの認証を使用して、あるスレッドからのリクエストが突然開始されるという競合状態が発生しますか? または、レールサーバーはマルチスレッド化されていないため、(リクエスト間の認証をリセットする限り) これは問題ではありませんか?

スレッド セーフの問題がなくても、リセットに失敗すると、以前のユーザーの資格情報が将来の要求で自動的に使用されるという危険性が依然としてあります。

更新: ActiveResource に不満を感じた後、独自の REST ライブラリを作成しました: https://github.com/DeepWebTechnologies/well_rested

4

2 に答える 2

7

Monkey は、クラスのhostuserおよびpasswordメソッドにパッチを適用します。ActiveResource::Base

class ActiveResource::Base
  # store the attribute value in a thread local variable
  class << self
    %w(host user password).each do |attr|               

      define_method(attr) do
        Thread.current["active_resource.#{attr}"]
      end

      define_method("#{attr}=") do |val|
        Thread.current["active_resource.#{attr}"] = val
      end
    end
  end
end

すべてのリクエストで資格情報を設定する

class ApplicationController < ActionController::Base

  around_filter :set_api_credentials

private 

  # set the credentials in every request
  def set_api_credentials
    ActiveResource::Base.host, 
      ActiveResource::Base.user, 
        ActiveResource::Base.password = current_user_credentials
    yield
  ensure
    ActiveResource::Base.host = 
      ActiveResource::Base.user = 
        ActiveResource::Base.password = nil
  end

  DEFAULT_HOST, DEFAULT_USER, DEFAULT_PASSWORD= [
    "http://www.foo.com", "user1", "user78102" ]

  def current_user_credentials
    current_user.present? ? 
      [ current_user.host, current_user.login, current_user.password] : 
      [ DEFAULT_HOST, DEFAULT_USER, DEFAULT_PASSWORD]
  end

end
于 2011-11-11T03:39:01.330 に答える
2

Active Resource 4.1.0 の時点で、これらの設定はスレッド ローカルであるため、この例では競合状態が発生しなくなりました。

これは関連するコミットです: https://github.com/rails/activeresource/commit/538588ddba9ffc9bf356790e9186dc7e6adad12f

于 2016-10-10T13:23:57.500 に答える