将api密钥添加到ActiveResource中的每个请求

我有两个RESTful Rails应用程序,我正试图互相交谈。 两者都是用Rails 3编写的(目前是beta3)。 对服务的请求将需要使用api密钥,这只是每个请求都需要的参数。 我似乎无法找到有关如何执行此操作的任何信息。

您可以通过site =方法定义资源连接到的URL。 应该有一个等效的query_params =方法或类似方法。

我找到了一篇与此相关的好博客文章,它是从2008年10月开始的,因此对Rails 3来说并不完全有用。

更新 :我有一个想法。 小型机架中间件或金属是否可以解决这个问题? 它可以直接通过请求,将其添加到api_key上。

使用model#prefix_options这是一个散列,用于将params传递给查询字符串(甚至作为Model.prefix部分的子集,例如“/ myresource /:param /”将替换为prefix_options [:param]的值。在前缀中找不到的哈希键将被添加到查询字符串中,这是我们想要的情况)。

class Model < ActiveResource::Base class << self attr_accessor :api_key end def save prefix_options[:api_key] = self.class.api_key super end end Model.site = 'http://yoursite/' Model.api_key = 'xyz123' m = Model.new(:field_1 => 'value 1') # hits http://yoursite:80/models.xml?api_key=xyz123 m.save 

我最近遇到了类似的问题,如果你在Rails3上,它支持使用自定义标题,这使得这些情况下的生活更加轻松。

在一边你提出请求,添加

headers['app_key'] = 'Your_App_Key'

到您从ActiveResource :: Baseinheritance的类

在您是服务器上,对于身份validation,只需将其作为

request.headers['HTTP_APP_KEY']

例如:

 class Magic < ActiveResource::Base headers['app_key'] = 'Your_App_Key' end 

现在Magic.get,Magic.find,Magic.post都将发送app_key

我有更好的解决方案! 我在中间件中尝试使用Rack,但我没有找到任何解决方案….

我建议你使用这个模块来覆盖ActiveReouse :: Base的方法

在/ lib / active_resource / extend /目录中添加此lib不要忘记取消注释
config / application.rb中的 “config.autoload_paths + =%W(#{config.root} / lib)”

 module ActiveResource #:nodoc: module Extend module AuthWithApi module ClassMethods def element_path_with_auth(*args) element_path_without_auth(*args).concat("?auth_token=#{self.api_key}") end def new_element_path_with_auth(*args) new_element_path_without_auth(*args).concat("?auth_token=#{self.api_key}") end def collection_path_with_auth(*args) collection_path_without_auth(*args).concat("?auth_token=#{self.api_key}") end end def self.included(base) base.class_eval do extend ClassMethods class << self alias_method_chain :element_path, :auth alias_method_chain :new_element_path, :auth alias_method_chain :collection_path, :auth attr_accessor :api_key end end end end end end 

在模型中

 class Post < ActiveResource::Base include ActiveResource::Extend::AuthWithApi self.site = "http://application.localhost.com:3000/" self.format = :json self.api_key = 'jCxKPj8wJJdOnQJB8ERy' schema do string :title string :content end end 

基于Joel Azemar的回答,但我不得不做出一些改动。首先,在我使用的活动资源gem(2.3.8)中,没有’new_element_path’,所以别名显然失败了..其次,我更新了令牌添加到查询的方式,因为它会在您自己添加更多参数时立即中断。 例如请求http://example.com/api/v1/clients.xml?vat=0123456789?token=xEIx6fBsxy6sKLJMPVM4 (注意?token = io&token =)

这是我更新的片段auth_with_api.rb;

 module ActiveResource #:nodoc: module Extend module AuthWithApi module ClassMethods def element_path_with_auth(id, prefix_options = {}, query_options = nil) query_options.merge!({:token => self.api_key}) element_path_without_auth(id, prefix_options, query_options) end def collection_path_with_auth(prefix_options = {}, query_options = nil) query_options.merge!({:token => self.api_key}) collection_path_without_auth(prefix_options, query_options) end end def self.included(base) base.class_eval do extend ClassMethods class << self alias_method_chain :element_path, :auth # alias_method_chain :new_element_path, :auth alias_method_chain :collection_path, :auth attr_accessor :api_key end end end end end end 

Active Resource目前没有将api密钥传递给远程服务的好方法。 将api_key作为参数传递会将其添加到远程服务上的对象属性中,我假设这不是您的行为。 这当然不是我需要的行为

活动资​​源对象的行为很像(简化的)Active Record对象。 如果您希望通过新参数,则可以通过将其添加为属性在AR对象上进行设置。 例如:

 jane = Person.create(:first => 'Jane', :last => 'Doe', :api_key => THE_API_KEY) 

它应该将api_key作为参数传递给所有其他参数。

我建议您有一个inheritance自ActiveResource::Base的基类,并覆盖self.collection_pathself.element_path类方法,以便始终注入API KEY,如:

 class Base < ActiveResource::Base def self.collection_path(prefix_options = {}, query_options = {}) super(prefix_options, query_options.merge(api_key: THE_API_KEY)) end def self.element_path(id, prefix_options = {}, query_options = {}) super(id, prefix_options, query_options.merge(api_key: THE_API_KEY)) end end class User < Base; end User.all # GET /users/?api_key=THE_API_KEY 

这将始终在您的ActiveResource方法调用中注入API_KEY。