Is it thread safe to set Active Resource HTTP authentication on a per-user basis?

只愿长相守 提交于 2019-11-27 15:08:50

Monkey patch the host, user and password methods of ActiveResource::Base class:

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

Now set the credentials in every request

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

As of Active Resource 4.1.0, those settings are thread local, so this example would not cause a race condition anymore.

This is the relevant commit if anyone is interested: https://github.com/rails/activeresource/commit/538588ddba9ffc9bf356790e9186dc7e6adad12f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!