Безопасно ли настраивать HTTP-аутентификацию Active Resource для каждого пользователя? - PullRequest
9 голосов
/ 11 ноября 2011

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, будет ли это вызывать состояние состязания, когда запросы из одного потока внезапно начинают использовать аутентификацию пользователя, чьи запросы выполняются одновременно в другом потоке?Или это не проблема (пока я сбрасываю аутентификацию между запросами), потому что серверы rails не являются многопоточными?

Даже если нет проблем с безопасностью потоков, все равно кажется рискованным, что если мне не удастся их сброситьучетные данные предыдущего пользователя будут автоматически использоваться будущими запросами.

Обновление: после разочарования в ActiveResource я написал свою собственную библиотеку REST: https://github.com/DeepWebTechnologies/well_rested

Ответы [ 2 ]

7 голосов
/ 11 ноября 2011

Обезьяна-патч host, user и 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
1 голос
/ 10 октября 2016

Начиная с Active Resource 4.1.0, эти настройки являются локальными для потока, поэтому этот пример больше не вызывает условия гонки.

Это релевантный коммит, если кому-то интересно: https://github.com/rails/activeresource/commit/538588ddba9ffc9bf356790e9186dc7e6adad12f

...