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.