Cat*_*ish 1 ruby-on-rails cancan ruby-on-rails-4
我刚刚使用带有devise/cancan/rolify的rails composer创建了一个rails应用程序,我正在查看它生成的一些代码,我不确定@user这个代码段的来源:
/controllers/users_controller.rb
class UsersController < ApplicationController
def index
authorize! :index, @user, :message => 'Not authorized as an administrator.'
@users = User.all
end
end
Run Code Online (Sandbox Code Playgroud)
/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :authenticate_user!
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_path, :alert => exception.message
end
end
Run Code Online (Sandbox Code Playgroud)
/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
end
end
Run Code Online (Sandbox Code Playgroud)
@user变量在哪里设置?我原本希望看到current_user那里.
编辑
我觉得我一定不能清楚地解释自己,所以试试吧.
1)这是有效的
def index
authorize! :index, @user, :message => 'Not authorized as an administrator.'
@users = User.all
end
Run Code Online (Sandbox Code Playgroud)
2)这是有效的
def index
authorize! :index, current_user, :message => 'Not authorized as an administrator.'
@users = User.all
end
Run Code Online (Sandbox Code Playgroud)
3)这不起作用
def index
authorize! :index, @my_user, :message => 'Not authorized as an administrator.'
@users = User.all
end
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么1)工作,但3)不?
CanCan期望控制器中存在current_user方法.
所以康康舞不依赖于色器件的current_user在授权,它会检查current_user是authorize!d做:action,并没有(因为你可能已经猜到了)检查第二个参数(在这种情况下@user)被授权做这个动作.
第二个参数authorize!实际上是要检查动作(第一个参数)的对象.换句话说(并假设代码中的情况):
康康舞将检查current_user有权限:index的@user
在您的评论中解释案例:
最奇怪的是,它在某种程度上也有效.当我以没有管理员角色的用户身份登录时,我收到消息"未经授权作为管理员",但当我以管理员身份登录时,我没有收到该消息
由于您没有向:admin您的非用户授予任何权限/models/ability.rb,因此无论执行何种操作以及执行了哪些对象,他们都无法执行任何操作,即使是在nil! - 这似乎是你的情况.另一方面,您已授予用户对/models/ability.rb中all()对象的:adminall(:manage)权限的权限:all,因此无论它们是什么,它们都可以对任何对象执行任何操作,甚至是nil!