Rails身份验证和请求变量未按预期工作

时间:2013-10-21 13:57:40

标签: ruby-on-rails ruby-on-rails-4

我正在开发一个rails应用程序,它允许可选的HTTP基本身份验证。

应该允许授权,但不是强制性的。

为此,我尝试在应用程序控制器中使用before_action,它将尝试查找与给定凭据匹配的用户,并将该用户或nil写入全局变量。

我尝试了这个,但似乎根本没有调用authenticate_with_http_basic的块(控制台没有显示我提供的用户名和密码,但是在块之外的日志记录工作):

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception


  before_action :authenticate

    def authenticate
        authenticate_with_http_basic do |username, password|
            logger.info "Login:"+username+"  "+password
            @auth_user = User.authenticate(username, password)
        end
    end

end

我试过这个:

def authenticate
    if user = authenticate_with_http_basic { |username, password| User.authenticate(username, password) }
        @auth_user = user
    end
end

我也试过了,这会引发错误undefined method 'split' for nil:NilClass。查看文档时,我发现在请求的一部分上调用了split。假设应该可以从应用程序控制器中的before_action访问request变量,我做错了吗?

def authenticate
    username, password = ActionController::HttpAuthentication::Basic::user_name_and_password(request);
    logger.info "Login:"+username+"  "+password
    @auth_user = User.authenticate(username, password)
end

我只需要一个简单的函数,它将用户名和密码作为字符串变量。我究竟做错了什么?还有另一种方法可以实现看似简单的功能吗?

更新

我尝试的东西似乎有效。我唯一的错误是使用常规的webbrowser来调试我的API。大多数Web浏览器在获得www-authenticate标头之前不会向服务器发送授权,即使用户明确将其包含在URL中也是如此。

只要它仅用作API或通过其他方式访问,这不应该是一个限制。但是,这种不提供授权对话框的可选授权不适用于常规浏览器(至少不能作为HTTP授权)。这不是Rails的问题,只是浏览器的构建方式。

1 个答案:

答案 0 :(得分:1)

你可能只是使用了错误的方法。这是ApiDock中的一个例子:

class AdminController < ApplicationController
  before_filter :authenticate

  def authenticate
    authenticate_or_request_with_http_basic('Administration') do |username, password|
      username == 'admin' && password == 'password'
    end
  end
end

有关详细信息,请参阅此问题:In Ruby on Rails, what does authenticate_with_http_basic do?

更新

如果没有请求基本身份验证,我没有看到任何问题。它按预期工作:

class HomeController < ApplicationController
  before_action :authenticate

  private

  def authenticate
    authenticate_with_http_basic do |username, password|
      logger.info "try basic-auth without requesting it: username=#{username} password=#{password}"
    end
  end
end

使用凭据调用操作:

curl -I "http://uschi:muschi@hamburg.onruby.dev:5000/"

给出以下日志:

[hamburg.onruby.dev] [127.0.0.1] [044cb7ea-56a9-4f] Started HEAD "/" for 127.0.0.1 at 2013-10-21 17:40:54 +0200
[hamburg.onruby.dev] [127.0.0.1] [044cb7ea-56a9-4f] Processing by HomeController#index as */*
[hamburg.onruby.dev] [127.0.0.1] [044cb7ea-56a9-4f] try basic-auth without requesting it: username=uschi password=muschi