1

我目前在我的 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 函数需要修改,以便“permit_login_via_get”方法可以使用它。

4

2 回答 2

1

问题是凭据将在 URL 中传递,因此非常可见,并且可能也缓存在用户的浏览器历史记录中。

于 2013-01-25T21:14:15.033 回答
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 任务;它从受 login_required 方法保护的 POS 服务器请求 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
于 2013-01-25T22:26:57.857 回答