Rails 3.2&设计:自定义authenticate_user!验证用户和管理员

时间:2013-01-09 11:57:57

标签: ruby-on-rails devise ruby-on-rails-3.2 rails-admin

我正在为用户和管理员使用两个单独的模型设计。我想替换authenticate_user!用我自己的函数,auth_user!这样管理员的权限就是用户权限的超集。我还写了一个函数actions_permitted,这样可以更容易地调用skip_before_filter。我在ApplicationController.rb中添加的代码如下所示。例如,我在控制器中使用它来写:actions_permitted:public => [:show],user:[:new,:create]。

但是,代码无法按预期运行:某些操作未经过正确身份验证,而其他操作则要求管理员在管理员应始终具有用户功能时也以用户身份登录。经过一些谷歌搜索后,我怀疑问题可能是当继承的模型调用actions_permitted时,它发生在ApplicationController级别而不是特定模型中。我还发现很多Stackoverflow都推荐使用CanCan,虽然我更喜欢坚持使用actions_permitted的简单语法,如果你能帮助我让它工作的话!

# app/controllers/application_controller.rb
#
# call with :user and :public defined as either :all or an array
# of symbols that represent methods. Admins can do everything that users
# can (by definition of auth_user!).
def self.actions_permitted(hash)
  # first process exceptions to user authentication
  if hash[:public] == :all
    # skip all filters and return
    skip_before_filter :auth_user!
    skip_before_filter :authenticate_admin!
    return
  elsif hash[:public].kind_of?(Array)
    # skip user authentication for methods in :public array
    skip_before_filter :auth_user!, only: hash[:public]
  end

  # then process exceptions to admin authentication
  if hash[:user] == :all
    # users can do everything, so skip all admin authenticatoin
    skip_before_filter :authenticate_admin!

  elsif hash[:user].kind_of?(Array)
    if hash[:public].kind_of?(Array)
      # Join the two arrays and skip admin authentication as not to filter
      # actions allowed by the public or by users
      skip_before_filter :authenticate_admin!, only: (hash[:user] | hash[:public])
    else
      # otherwise, simply skip admin authentication for actions allowed by users
      skip_before_filter :authenticate_admin!, only: hash[:user]
    end

  elsif hash[:public].kind_of?(Array)
    # skip admin authentication for actions allowed by the public
    skip_before_filter :authenticate_admin!, only: hash[:public]
  end

end

# checks if user OR admin is authenticated.
def auth_user!(opts = {})
  # return (authenticate_user! || authenticate_admin!)
  return (env['warden'].authenticated?(:user) ||
          env['warden'].authenticated?(:admin))
end

1 个答案:

答案 0 :(得分:3)

原来问题出现在auth_user!中。对于任何想要在将来使用此代码的人,这里是更正:

def auth_user!(opts = {})
  if admin_signed_in?
    authenticate_admin!
  else
    authenticate_user!
  end
end