我目前在ApplicationController中有一个before_filter,用于凭据验证。我还希望能够在我直接访问URL时验证用户凭据(即,从脚本而不是从浏览器登录表单/会话)。通过GET请求接受用户凭据是否存在问题?
application_controller.rb
before_filter :login_required
def login_required
reset_session if session[:last_seen] < Rails.configuration.admin_timeout.minutes.ago rescue nil
return true if session[:user]
if (!params[:login].nil? && !params[:password].nil?) && session[:user] = User.authenticate(params[:login], params[:password])
return true
else
render :nothing => true, :status => 401
return false
end
flash[:alert] = 'Please login to continue'
redirect_to login_url and return false
end
如果这不是一种可接受的做法,我希望只能在某些“安全”的情况下这样做。控制器动作。例如:
product_controller.rb
before_filter :do_something
permit_login_via_get :only => [:index]
def index
# Do some stuff in here. This should be accessible via http://mydomain.com/products?login=admin&password=yeahlikeidtellyouthat
end
所以现在我的login_requred函数需要修改,以便&#39; permit_login_via_get&#39;方法适用于它。
答案 0 :(得分:1)
问题是凭据将在URL中传递,因此非常明显,也可能在用户的浏览器历史记录中缓存。
答案 1 :(得分:1)
好的,所以我考虑了一下,并决定最好为我的每个应用程序创建API密钥,并使用Net :: HTTP请求,设置包含API密钥的自定义标头。这样就没有通过URL发送的用户凭据。现在关于这种方法的“安全”与否,或者我需要做些什么才能使其安全是另一回事。但到目前为止,我是如何做到的,它似乎正在起作用:
application.rb(经理申请)
# API Keys
config.api_key = "somelongstringofcharacters"
config.pos_api_key = "anotherlongstringofcharacters"
config.website_api_key = "yetANOTHERlongstringofcharacters"
POS和网站应用程序中的application.rb同样适用于上面的示例。
application_controller.rb(所有应用程序)
before_filter :login_required
def login_required
reset_session if session[:last_seen] < Rails.configuration.admin_timeout.minutes.ago rescue nil
return true if session[:user]
unless request.headers["X-API-Key"].nil?
if request.headers["X-API-Key"] == Rails.configuration.api_key
return true
else
render :nothing => true, :status => 401
return false
end
end
flash[:alert] = 'Please login to continue'
redirect_to :controller => :users, :action => :login
return false
end
这样所有方法都是私有的(除了那些具有skip_before_filter:login_required的方法)并且如果您通过使用表单使用登录/密码组合登录会话,或者如果您已经做出请求,则可以访问这些方法有一个带有正确应用程序密钥的“X-API-Key”标头。
以下是通过Manager应用程序运行的示例Rake任务;它从POS服务器请求一个受login_required方法保护的JSON文件:
desc "Test Task so that larger projects don't need to be run through"
task :testing => :environment do
require "net/http"
require "uri"
url = URI.parse("http://myposdomain/items.json?all=true&category=Wines")
req = Net::HTTP::Get.new(url.path)
req.add_field("X-API-Key", Rails.configuration.pos_api_key)
res = Net::HTTP.new(url.host, url.port).start do |http|
http.request(req)
end
myposdomain_wines = res.body
end