本文介绍了在每个用户的基础上设置 Active Resource HTTP 身份验证是否线程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 修补 hostuserpassword 方法的 >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 身份验证是否线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 07:16