1

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

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

为此,我尝试before_action在应用程序控制器内部使用 a ,它将尝试找到与给定凭据匹配的用户,并将该用户或 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。request我只是假设变量应该可以从应用程序控制器中的 before_action 访问,我做错了吗?

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

我只需要一个简单的函数,将用户名和密码作为字符串变量提供给我。我究竟做错了什么?有没有另一种方法来完成这个看似简单的功能?

更新

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

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

4

1 回答 1

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

有关详细信息,请参阅此问题:在 Ruby on Rails 中,authenticate_with_http_basic 做了什么?

更新

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

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
于 2013-10-21T14:29:31.540 回答