【问题标题】:HTTP Basic Auth for some (not all) controllers某些(不是全部)控制器的 HTTP 基本身份验证
【发布时间】:2014-03-10 12:18:52
【问题描述】:

使用 Rails 3.2。

我有六个控制器,想用http_basic_authenticate_with 保护一些(但不是全部)。

我不想手动将http_basic_authenticate_with 添加到每个控制器(我将来可能会添加另一个控制器而忘记保护它!)。似乎答案是把它放在application_controller.rb:except arg 中,它会列出应该受保护的控制器。问题是,:except 子句需要方法名称而不是外部控制器模块名称,例如:

http_basic_authenticate_with :name => 'xxx', :password => 'yyy', :except => :foo, :bar

然后我想“等等,因为我已经将受保护的控制器分组在 routes.rb 中,让我们把它放在那里。”所以我在我的路线中尝试了这个:

  scope "/billing" do
    http_basic_authenticate_with :name ...
    resources :foo, :bar ...
  end

但现在我明白了

undefined method `http_basic_authenticate_with'

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 一个选择是有一个class ProtectedController < ApplicationController,把http_basic_authenticate放在那里,并从那里继承受保护的控制器。
  • 如果您碰巧使用 devise 进行身份验证,您可以使用 devise 而不是 rails 启用基本身份验证 - github.com/plataformatec/devise/wiki/… - 可能与您的情况无关?
  • Sergio,这会让我回到我试图避免的同一个地方 - 我必须手动添加我想要保护的每个新控制器。如果我愿意这样做,我可以简单地将 http_base_authenticate 行放入每个控制器中。
  • @house9 我没有听说过 Devise,谢谢你的提示。我去看看。

标签: ruby-on-rails authentication


【解决方案1】:

像 Rails 那样做。

# rails/actionpack/lib/action_controller/metal/http_authentication.rb

def http_basic_authenticate_with(options = {})
  before_action(options.except(:name, :password, :realm)) do
    authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
      name == options[:name] && password == options[:password]
    end
  end
end

http_basic_authenticate_with 所做的只是添加一个before_action。您也可以自己轻松地做同样的事情:

# application_controller.rb

before_action :http_basic_authenticate

def http_basic_authenticate
  authenticate_or_request_with_http_basic do |name, password|
    name == 'xxx' && password == 'yyy'
  end
end

这意味着您可以在不需要这种行为的控制器中使用skip_before_action

# unprotected_controller.rb

skip_before_action :http_basic_authenticate

【讨论】:

  • 感谢@SamBlake。这应该是公认的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2021-03-21
  • 2011-11-12
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多