3

私は他の誰かのコードで作業していますが、Rails の経験がなく、CanCan と Devise に問題があります。

ログインしようとすると(以前は機能していたことがわかっている資格情報を使用し、DBを確認してリセット機能を正常に使用しました)、エラー画面が表示されます。

CanCan::AccessDenied in AdminController#index

You are not authorized to access this page.

app/controllers/admin_controller.rb:4:in `index'
config/initializers/quiet_assets.rb:6:in `call_with_quiet_assets'

そしてターミナルで

Started POST "/users/sign_in" for 127.0.0.1 at 2012-11-14 13:13:01 +0000
  Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓",  "authenticity_token"=>"T8CJkCIEA3r7ROiknVp/vbEgeKCBZEjl3uYd+46G7no=", "user"=>{"email"=>"pass@user.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
WARNING: Can't verify CSRF token authenticity
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`email` = 'pass@user.com' LIMIT 1
(0.2ms)  BEGIN
(0.3ms)  UPDATE `users` SET `last_sign_in_at` = '2012-11-14 11:10:56', `current_sign_in_at` = '2012-11-14 13:13:01', `sign_in_count` = 219, `updated_at` = '2012-11-14 13:13:01' WHERE `users`.`id` = 1
(0.1ms)  COMMIT
Redirected to http://core.lvh.me:3000/admin
Completed 302 Found in 355ms


Started GET "/admin" for 127.0.0.1 at 2012-11-14 13:13:02 +0000
  Processing by AdminController#index as HTML
Completed 500 Internal Server Error in 265ms

CanCan::AccessDenied (You are not authorized to access this page.):
  app/controllers/admin_controller.rb:4:in `index'
  config/initializers/quiet_assets.rb:6:in `call_with_quiet_assets'

admin_controller.rb

class AdminController < ApplicationController

  def index
   authorize! :index, :admin (#line 4)
  end

アビリティ.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    case user.role_name

    when "super_admin"
      # can do everything
      can :manage, :all

    when "franchise_admin"
      can [:read, :search, :all, :up_down_index], Article
      can [:old_feed, :sites, :new_feed], MobileFeed
      can [:new, :read, :update], SiteSpecificArticle, site_id: user.site_id
      can [:index, :new_site_essentials], :admin


    when "franchise_editor"
      can [:new, :read, :update], SiteSpecificArticle { |ssa| ssa.site.customer.sites.include?(user.site) }
      can [:old_feed, :sites, :new_feed], MobileFeed
      can [:read, :search, :all, :up_down_index], Article

    when "site_admin"
      # can CRUD users for their site
      can :manage, User, site_id: user.site_id
      # can edit content for their site
      can [:read, :update], ArticleSitePermission, site_id: user.site_id
      can [:read, :update], CoreArticleSiteVisibility, site_id: user.site_id
      can [:new, :read, :update], SiteSpecificArticle, site_id: user.site_id
      can [:new, :read, :update], FrontPageCampaign, site_id: user.site_id
      can [:new, :read, :update], FrontPageTimeBasedArticle, site_id: user.site_id
      can [:new, :read, :update], FrontpageArticle, site_id: user.site_id
      can [:index, :new_site_essentials], :admin
      can [:read, :search, :all, :up_down_index, :hidden_in_this_site], Article
      can [:old_feed, :sites, :new_feed], MobileFeed
      can [:index, :create], TrackMood
      can :site_styles, Site

    when "editor"
      # can edit content for their site
      can [:read, :update], ArticleSitePermission, site_id: user.site_id
      can [:read, :update], CoreArticleSiteVisibility, site_id: user.site_id
      can [:new, :read, :update], SiteSpecificArticle, site_id: user.site_id
      can :manage, FrontPageCampaign, site_id: user.site_id
      can :manage, User, site_id: user.site_id
      can [:new, :read, :update], FrontPageTimeBasedArticle, site_id: user.site_id
      can [:new, :read, :update], FrontpageArticle, site_id: user.site_id
      can [:old_feed, :sites, :new_feed], MobileFeed
      can [:index, :new_site_essentials], :admin
      can [:read, :search, :all, :up_down_index, :hidden_in_this_site], Article
      can [:index, :create], TrackMood
      can :site_styles, Site

    else
      # guest user (not logged in)
      can [:read, :search, :up_down_index], Article
      can [:old_feed, :sites, :new_feed], MobileFeed
      can [:index, :create], TrackMood
      can :site_styles, Site
    end
  end
end

この問題に関する助けをいただければ幸いです。問題をデバッグするためのもう 1 つのステップであっても。

ありがとうございました

4

2 に答える 2

3

Github の CanCan wiki には、次のように記載されています。

「authorize_resource を追加すると、authorize! を呼び出す前のフィルターが作成され、存在する場合はリソース インスタンス変数が渡されます。インスタンス変数が設定されていない場合 (インデックス アクションなど)、クラス名が渡されます。たとえば、各アクションの前にこれを行う ProductsController があります。」

authorize!(params[:action], @product || Product)

問題は、次のように、管理オブジェクトまたはモデルを実際に承認する必要があるときに、:admin シンボルの :index アクションを承認しようとしていることです。

authorize!(:index, @admin)

あなたは権限を誤解していると思います!メソッドを使用して、ロール :admin のインデックス アクションを承認しようとしましたが、すべての CanCan は current_ability に基づいて承認されます。これは、ログイン後のユーザー セッションで最初に設定されると想定されています。CanCan は、このデフォルトの ApplicationController メソッドを使用して、これを行います。

def current_ability
    @current_ability ||= Ability.new(current_user)
end

ただし、これは、現在のユーザーを返す current_user という別のメソッドが必要であることを意味します (doh)。current_user.adminこの設定があるかどうかを確認し、そうでない場合は設定して :admin を @admin に変更します(インスタンス化する必要があります。 (?)のようなものだと思います)。

もう 1 つ: デバッグのためだけにこのような認証を行っている場合は問題ありませんが、実際にこのようにすべてのアクションを手動で認証することを考えている場合は、しないでください。CanCan には というメソッドがload_and_authorize_resourceあり、コントローラーのすべてのアクションに対して current_user を承認し、変数 @model (@products など) を次のようにインスタンス化しますProduct.accessible_by(current_ability)。これは、ユーザーが自分のプロファイルを編集するなど、場合によってのみ表示または管理できるものがある場合に非常にうまく機能します。もちろん、これはability.rbファイルでセットアップする必要があります。この方法は次のようになります。

class AdminController < ApplicationController

    load_and_authorize_resource

    def index
        # @admins here will have every admin that the user can see
    end

end

また、承認する必要のないアクションがある場合は、次のように言うことができます。

load_and_authorize_resource, :only => [:action1, :action2]
load_and_authorize_resource, :except => [:action1, :action2]

またはまた:

load_and_authorize_resource
skip_authorize_resource, :only => [:action1]
skip_authorize_resource, :except => :action2 #can be both an array or single symbol

これがあなたとこの問題を抱えている人に役立つことを願っています:)

于 2012-11-15T03:41:43.187 に答える
0

次のように変更してみてください。

class AdminController < ApplicationController

  def index
    authorize! :index, :super_admin (#line 4)
  end
于 2012-11-14T17:50:18.940 に答える