是否可以在每个用户的基础上设置Active Resource HTTP身份validation的线程安全?

Active Resource可以使用在类级别设置的HTTP身份validation。 例如:

class Resource < ActiveResource::Base end Resource.user = 'user' Resource.password = 'password' 

要么

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

但是,如果我根据用户登录使用不同的HTTP身份validation怎么办? 如果我更改Resource.user和Resource.password,是否会导致竞争条件,其中来自一个线程的请求突然开始使用其请求在另一个线程中同时运行的用户的身份validation? 或者这是一个非问题(只要我重置请求之间的身份validation),因为rails服务器不是multithreading的?

即使没有线程安全问题,如果我无法重置它们仍然存在风险,以前用户的凭据将在未来的请求中自动使用。

更新:在对ActiveResource感到沮丧之后,我编写了自己的REST库: https //github.com/DeepWebTechnologies/well_rested

Monkey补丁ActiveResource::Base类的hostuserpassword方法:

 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 

从Active Resource 4.1.0开始,这些设置是线程本地的,因此该示例不再导致竞争条件。

如果有人感兴趣,这是相关提交: https : //github.com/rails/activeresource/commit/538588ddba9ffc9bf356790e9186dc7e6adad12f