我正在使用其他人的代码,而且我对Rails缺乏经验,而且我对CanCan&设计。
当尝试登录时(使用我知道的凭据,因为他们以前工作过,我已经检查了数据库并成功使用了重置功能),我收到一个错误屏幕说明。
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
ability.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
对此事的任何帮助将不胜感激。即使这只是尝试调试问题的另一个步骤。
谢谢
答案 0 :(得分:2)
Github上的CanCan wiki声明:
“添加authorize_resource会生成一个调用authorize!的before过滤器,如果存在则传递资源实例变量。如果未设置实例变量(例如在index操作中),它将传入类名。例如,如果我们有一个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)。检查你是否有这个设置,如果没有,那么设置它并更改:admin到@admin(你必须实例化,我认为是current_user.admin
(?))。
还有一件事:如果你正在进行这样的授权只是为了调试,好吧,没问题,但是如果你正在考虑实际授权每个动作都是这样的,请不要。 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
我希望这可以帮助你和任何有这个问题的人:)
答案 1 :(得分:0)
您可以尝试更改为:
class AdminController < ApplicationController
def index
authorize! :index, :super_admin (#line 4)
end