Using authlogic_api for Rails REST API access

前端 未结 3 2197
误落风尘
误落风尘 2021-02-09 07:44

I am writing a Rails back-end API for a Steam game that is only accessed via REST calls, so no user-specific authentication is required. I am trying to implement the authlogic_a

相关标签:
3条回答
  • 2021-02-09 08:32

    Solved this by following the Authlogic example, and just substituting a ClientAccount model for the User model. So in my Application controller I have:

    before_filter :require_client
    
    def require_client
      unless current_client
        store_location
        render :text => 'Authentication failed', :status => 401
        return false
      end
    end
    
    def require_no_client
      if current_client
        store_location
        render :text => 'Client session already exists', :status => 401
        return false
      end
    end
    
    def current_client_session
      return @current_client_session if defined?(@current_client_session)
      @current_client_session = ClientSession.find
    end
    
    def current_client
      return @current_client if defined?(@current_client)
      @current_client = current_client_session && current_client_session.record
    end
    

    The ClientAccount model acts_as_authentic, and the ClientSession model handles creating and destroying the sessions for Authlogic (authenticate_with ClientAccount):

    class ClientSessionsController < ApplicationController
      before_filter :require_no_client, :only => [:new, :create]
      before_filter :require_client, :only => :destroy
    
      def new
        @client_session = ClientSession.new
      end
    
      def create
        @client_session = ClientSession.new(params[:client_session])
        if @client_session.save
          redirect_back_or_default account_url
        else
          render :action => :new
        end
      end
    
      def destroy
        current_client_session.destroy
        redirect_back_or_default new_client_session_url
      end
    end
    

    This solution has worked well, as we're able to generate different API key/signature combos for different clients, which gives us additional usage data. The only "gotcha" is if you're doing something like a multipart file upload, since the POST hash uses the raw POST data.

    0 讨论(0)
  • 2021-02-09 08:44

    You may not need the overhead of Authlogic.

    If you are generating a URL that the client will then send, just add an expiration timestamp, and do an MD5 hash (signature) on the entire URL, adding the result as a final query paramter.

    Please a before_filter on the controller action, i.e. a signed_url method that will validate the URL. This method should get the URL from the request object. Verify the expiration has not passed. Remove the signature from the URL to place it in the same form as was used to generate the original URL, do so, and verify a match. Voila.

    Expiration is important to be sure that URL's cannot be re-used later.

    This is a great method to centralize as an alternate way to authorize requests without requiring a login. As long as you have generated the URL, it will be valid until expiration from any host.

    0 讨论(0)
  • 2021-02-09 08:45

    Actually, it's much simpler. Using all that code from the Authlogic example is somewhat overkill - it mainly manages storing session details, which you don't need to do for the Application (also known as Client) session. The Client session is re-confirmed at every request.

    All you need is:

    models\client.rb

    class Client < ActiveRecord::Base
      acts_as_authentic do |config|
      end
    end
    

    models\client_session.rb

    class ClientSession < Authlogic::Session::Base
      api_key_param 'app_key'
    end
    

    controllers\application_controller

    before_filter :verify_client
    
    def verify_client
      @client_session = ClientSession.new()
      unless @client_session.save # if client session not successfully created using the api_key and signature, render an error and block the request
        @error = {:description => "Couldn't validate client application."}
        render :template => 'errors/error.xml.builder'
      end
    end
    

    You also need to run a migration to create the clients table. Not all of the fields below are necessary, but they won't hurt.

    class CreateClients < ActiveRecord::Migration
      def self.up
        create_table :clients do |t|
          # human fields
          t.string :name
          t.string :owner
          t.string :owner_email
          t.string :owner_phone
          # login fields
          t.string :api_key, :null => false
          t.string :api_secret, :null => false
          t.string :password_salt
          t.string :persistence_token
          t.string :perishable_token
          # automagical fields (courtesy of authlogic & authlogic_api)
          t.integer :failed_login_count
          t.datetime :last_request_at
          t.integer :request_count
          t.string :last_request_ip
          # automagical fields (courtesy of rails)
          t.timestamps
        end
      end
    
      def self.down
        drop_table :clients
      end
    end
    
    0 讨论(0)
提交回复
热议问题