使用authlogic_api进行Rails REST API访问

我正在为只能通过REST调用访问的Steam游戏编写Rails后端API,因此不需要特定于用户的身份validation。 我正在尝试为Authlogic gem实现authlogic_api插件 ,该插件使用api_key / signature机制来限制访问。 我已经实现了rdocs中概述的ApplicationSessionApplicationAccount模型,但我不确定如何修改我的ApplicationController以限制访问。

查看源代码,authlogic_api插件似乎修改了Authlogic中的ActsAsAuthenticSession模块。 但由于这实际上是“单一访问”身份validation,要求在每次请求时传递API密钥和签名,我不会看到会话如何成为一个因素。

有没有人在他们的应用程序中成功实现了authlogic_api? 如果是这样,您会分享设置ApplicationController的方法吗?

实际上,它更简单。 使用Authlogic示例中的所有代码有点过分 – 它主要管理存储会话详细信息,您不需要为应用程序(也称为客户端)会话执行此操作。 每次请求都会重新确认客户端会话。

所有你需要的是:

型号\ client.rb

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

型号\ client_session.rb

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

控制器\ 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 

您还需要运行迁移以创建clients表。 并非所有下面的字段都是必要的,但它们不会受到伤害。

 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 

您可能不需要Authlogic的开销。

如果您要生成客户端随后将发送的URL,则只需添加到期时间戳,并对整个URL执行MD5哈希(签名),并将结果添加为最终查询参数。

请在控制器操作上使用before_filter,即将validationURL的signed_url方法。 此方法应从请求对象获取URL。 validation过期未通过。 从URL中删除签名,使其与用于生成原始URL的格式相同,执行此操作并validation匹配项。 瞧。

过期非常重要,以确保以后无法重复使用URL。

这是一种很好的方法,可以集中作为授权请求而无需登录的替代方法。 只要您生成了URL,它就会在任何主机到期之前有效。

通过遵循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模型为acts_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数据。