问题描述
Active Resource 可以使用在类级别设置的 HTTP 身份验证.例如:
Active Resource can make use of HTTP authentication set at the class level. For instance:
class Resource < ActiveResource::Base
end
Resource.user = 'user'
Resource.password = 'password'
或
Resource.site = "http://user:[email protected]/"
但是如果我根据登录的用户使用不同的 HTTP 身份验证怎么办?如果我更改 Resource.user 和 Resource.password,是否会导致竞争条件,即来自一个线程的请求突然开始使用其请求在不同线程中同时运行的用户的身份验证?或者这不是问题(只要我在请求之间重置身份验证),因为 Rails 服务器不是多线程的?
But what if I use different HTTP authentication based on which user is logged in? If I change Resource.user and Resource.password, is that going to cause a race condition where requests from one thread suddenly start using the authentication of a user whose requests are running simultaneously in a different thread? Or is this a non-issue (as long as I reset the authentication between requests) because rails servers are not multithreaded?
即使没有线程安全问题,如果我未能重置它们,以前用户的凭据将被未来的请求自动使用,这似乎仍然存在风险.
Even if there's no thread safety problem, it still seems risky that if I fail to reset them, the previous user's credentials will be used automatically by future requests.
更新:在对 ActiveResource 感到沮丧之后,我编写了自己的 REST 库:https://github.com/DeepWebTechnologies/well_rested
推荐答案
Monkey 修补 host
、user
和 password
方法的 >ActiveResource::Base
类:
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
这篇关于在每个用户的基础上设置 Active Resource HTTP 身份验证是否线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!