2

私はユーザーと管理者のために2つの別々のモデルでdeviseを使用しています。authenticate_userを置き換えたかったのです!私自身の関数、auth_userで!管理者の権限がユーザーの権限のスーパーセットになるようにします。また、skip_before_filterの呼び出しを簡単にする関数actions_permittedも作成しました。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
4

1 に答える 1

3

問題はauth_user!にあったことが判明しました。将来このコードを使用したい人のために、ここに修正があります:

def auth_user!(opts = {})
  if admin_signed_in?
    authenticate_admin!
  else
    authenticate_user!
  end
end
于 2013-01-09T22:22:58.947 に答える