tutorial rails que ejemplos curso aprender ruby-on-rails ruby ruby-on-rails-3 activeresource

ruby on rails - rails - Agregue una clave de API a cada solicitud en ActiveResource



ruby on rails tutorial (7)

Un objeto de recurso activo se comporta de forma muy parecida a un objeto de registro activo (simplificado). Si desea pasar un nuevo parámetro, puede configurarlo en el objeto AR agregándolo como un atributo. p.ej:

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

debe pasar la api_key como parámetro, junto con todos los demás.

Tengo 2 aplicaciones de RESTful Rails que trato de hacer para hablar entre ellas. Ambos están escritos en Rails 3 (beta3 en este momento). Las solicitudes al servicio requerirán el uso de una clave de API que es solo un parámetro que debe estar en cada solicitud. Parece que no puedo encontrar ninguna información sobre cómo hacer esto.

Usted define la URL a la que se conecta el recurso a través del sitio = método. Debería haber un método query_params = equivalente o similar.

Hay una buena publicación de blog que encontré relacionada con esto y es de octubre de 2008, por lo que no es exactamente útil para Rails 3.

Actualización : tuve un pensamiento. ¿Un pequeño middleware Rack o Metal sería la respuesta a esto? Podría simplemente pasar la solicitud, al virar es api_key.


Un recurso activo actualmente no tiene una buena forma de pasar una clave de API al servicio remoto. Pasar api_key como parámetro lo agregará a los atributos de los objetos en el servicio remoto, supongo que este no es el comportamiento que usted desea. Ciertamente no era el comportamiento que necesitaba


Utilice el modelo # prefix_options que es un hash para pasar los parámetros a la cadena de consulta (o incluso como substiciones para las partes del Model.prefix, por ejemplo, "/ myresource /: param /" será reemplazado por el valor de prefix_options [: param]. Cualquier las claves hash que no se encuentran en el prefijo se agregarán a la cadena de consulta, que es lo que queremos en su caso).

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


¡Tengo una solución mucho mejor! Intento con Rack en middleware pero no encuentro ninguna solución de esta manera ...

Te propongo este módulo para anular los métodos de ActiveReouse :: Base

Agregue esta lib en el directorio / lib / active_resource / extend / no olvide el comentario
"config.autoload_paths + =% W (# {config.root} / lib)" en config / application.rb

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

en modelo

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


Recientemente me enfrenté a un problema similar, si estás en Rails3, admite el uso de un encabezado personalizado que hace la vida mucho más fácil para estas situaciones.

En el lado desde el que realiza la solicitud, agregue

headers[''app_key''] = ''Your_App_Key''

a la clase que estás heredando de ActiveResource :: Base

En su servidor, para Autenticación, simplemente recíbalo como

request.headers[''HTTP_APP_KEY'']

Por ejemplo:

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

ahora Magic.get, Magic.find, Magic.post todos enviarán la app_key


Basado en la respuesta de Joel Azemar, pero tuve que hacer algunos cambios. Antes que nada, en la joya de recursos activos que utilicé (2.3.8), no hay ''ruta_elementos_nuevos'', por lo que el alias obviamente falló. Segundo, actualicé la forma en que se agrega el token a la consulta, porque como estaba, se rompería tan pronto como agregaras más params. Por ejemplo, solicitar http://example.com/api/v1/clients.xml?vat=0123456789?token=xEIx6fBsxy6sKLJMPVM4 (notice? Token = io & token =)

Aquí está mi snippet actualizado 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


Recomiendo que tenga una clase base heredando de ActiveResource::Base y anule los métodos de clase self.collection_path y self.element_path para inyectar siempre la clave API algo así como:

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

Esto siempre inyectará su API_KEY en sus llamadas al método ActiveResource.