Add api key to every request in ActiveResource

前端 未结 7 1719
北荒
北荒 2020-12-31 01:20

I have 2 RESTful Rails apps I\'m trying to make talk to each other. Both are written in Rails 3 (beta3 at the moment). The requests to the service will require the use an ap

相关标签:
7条回答
  • 2020-12-31 02:00

    An Active Resource Object behaves much like a (simplified) Active Record object. If you wish to pass through a new param, then you can set it on the AR object by adding it as an attribute. eg:

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

    it should pass the api_key as a parameter, along with all the others.

    0 讨论(0)
  • 2020-12-31 02:09

    I have much nicer solution ! I try with Rack in middleware but i no find any solution in this way....

    I propose you this module for override methods of ActiveReouse::Base

    Add this lib in /lib/active_resource/extend/ directory don't forget uncomment
    "config.autoload_paths += %W(#{config.root}/lib)" in 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
    

    in model

    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
    
    0 讨论(0)
  • 2020-12-31 02:15

    I recently was faced with a similar issue, if you are on Rails3, it supports using custom header which makes life much easier for these situations.

    On the side you are making the request from, add

    headers['app_key'] = 'Your_App_Key'

    to the class you are inheriting from ActiveResource::Base

    On you are server, for Authentication, simply receive it as

    request.headers['HTTP_APP_KEY']

    For Example:

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

    now Magic.get, Magic.find, Magic.post will all send the app_key

    0 讨论(0)
  • 2020-12-31 02:18

    Use model#prefix_options which is a hash for passing params into query string (or even as substitions for parts of the Model.prefix, e.g. "/myresource/:param/" will be replaced by the value of prefix_options[:param] . Any hash keys not found in the prefix will be added to the query string, which is what we want in your case).

    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
    
    0 讨论(0)
  • 2020-12-31 02:18

    An Active Resource currently has no good way of passing an api key to the remote service. Passing api_key as a parameter will add it to the objects attributes on the remote service, I assume that this is not the behaviour you'd except. It certainly wasn't the behaviour I needed

    0 讨论(0)
  • 2020-12-31 02:19

    Based on Joel Azemar's answer, but I had to make some changes.. First of all, in the active resource gem I used (2.3.8), there is no 'new_element_path', so aliasing that obviously failed.. Second, I updated the way the token is added to the query, because as was, it would break as soon as you add more params yourself. E.g. request for http://example.com/api/v1/clients.xml?vat=0123456789?token=xEIx6fBsxy6sKLJMPVM4 (notice ?token= i.o. &token=)

    Here's my updated snippet 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
    
    0 讨论(0)
提交回复
热议问题