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?