api for Rails REST API访问

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

查看源代码,看起来authlogic_api插件修改了Authlogic中的ActsAsAuthentic和Session模块。 但是,由于这基本上是“单一访问”认证,要求每个请求都传递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

您还需要运行迁移来创建客户端表。 并非以下所有领域都是必要的,但他们不会受到伤害。

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,即一个将验证URL的signed_url方法。 该方法应该从请求对象获取URL。 验证到期没有通过。 从网址中移除签名以将其与原始网址生成相同,然后验证匹配。 瞧。

过期是非常重要的,以确保URL不能在以后重新使用。

这是集中的一种很好的方法,可以作为批准请求而不需要登录的备用方式。 只要您生成了该网址,它就会有效,直到从任何主机到期为止。


通过遵循Authlogic示例来解决这个问题,并且只需将UserAccount模型替换为用户模型。 所以在我的应用程序控制器中我有:

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数据。

链接地址: http://www.djcxy.com/p/46375.html

上一篇: api for Rails REST API access

下一篇: How does this SQL query to update a row if exists, or insert if not, work?