Использование authlogic_api для доступа к REST API Rails - PullRequest
7 голосов
/ 24 июня 2010

Я пишу бэкэнд-API Rails для игры в Steam, доступ к которому осуществляется только через вызовы REST, поэтому аутентификация для конкретного пользователя не требуется. Я пытаюсь реализовать плагин authlogic_api для Authlogic gem, который использует механизм api_key / signature для ограничения доступа. Я реализовал модели ApplicationSession и ApplicationAccount , как указано в rdocs, но я не уверен, как изменить мой ApplicationController для ограничения доступа.

Глядя на источник, кажется, что плагин authlogic_api изменяет модули ActsAsAuthentic и Session от Authlogic. Но так как это по сути аутентификация «с единым доступом», требующая передачи ключа API и подписи при каждом запросе, я не вижу, как сеансы будут иметь значение.

Кто-нибудь успешно реализовал authlogic_api в своих приложениях? Если да, поделитесь ли вы подходом к настройке ApplicationController ?

Ответы [ 3 ]

4 голосов
/ 03 октября 2010

На самом деле все гораздо проще.Использование всего этого кода из примера Authlogic несколько излишне - он в основном управляет хранением деталей сеанса, что вам не нужно делать для сеанса приложения (также известного как клиент).Сеанс клиента подтверждается при каждом запросе.

Все, что вам нужно:

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

Вам также необходимо запустить миграцию для создания таблицы клиентов.Не все поля ниже обязательны, но они не повредят.

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 голосов
/ 08 июля 2010

Решил эту проблему, следуя примеру Authlogic , и просто подставив модель ClientAccount для модели User. Итак, в моем контроллере приложений у меня есть:

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

Модель ClientAccount действовать_as_authentic, а модель ClientSession обрабатывает создание и уничтожение сеансов для 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

Это решение хорошо сработало, поскольку мы можем создавать различные комбинации ключей и сигнатур API для разных клиентов, что дает нам дополнительные данные об использовании. Единственная «ошибка» - это если вы выполняете что-то вроде многократной загрузки файла, поскольку хеш POST использует необработанные данные POST.

0 голосов
/ 26 июня 2010

Возможно, вам не понадобятся служебные данные Authlogic.

Если вы генерируете URL-адрес, который клиент затем отправит, просто добавьте метку времени истечения и сделайте хэш (подпись) MD5 для всего URL-адреса,добавление результата в качестве окончательного параметра запроса.

Пожалуйста, используйте before_filter для действия контроллера, то есть метод signature_url, который будет проверять URL.Этот метод должен получить URL из объекта запроса.Убедитесь, что срок действия не прошел.Удалите подпись из URL-адреса, чтобы поместить ее в ту же форму, которая использовалась для создания исходного URL-адреса, сделайте это и проверьте соответствие.Вуаля.

Срок действия важен, чтобы быть уверенным, что URL-адреса не могут быть повторно использованы позже.

Это отличный способ централизации в качестве альтернативного способа авторизации запросов без входа в систему.Пока вы сгенерировали URL, он будет действителен до истечения срока действия с любого хоста.

...