当我以不同用户身份登录时访问users/1/edit
不会引发AccessDenied错误,我不明白为什么:
authorize_resource only: [:edit, :update]
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
redirect_to @user
else
render 'edit'
end
end
能力等级:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
can :read, :all
can :create, User
can :create, Group
can :update, User, id: user.id
end
end
如果我将authorize_resource
更改为load_and_authorize_resource
,那么它会按预期工作。但这当然不应该是相关的吗?
答案 0 :(得分:1)
您的代码仅授权用户访问编辑和更新操作,而不是@user
对象
你必须像这样手动授权对象
试试这个,
def edit
@user = User.find(params[:id])
authorize! :update, @user
end
def update
@user = User.find(params[:id])
authorize! :update, @user
if @user.update_attributes(params[:user])
redirect_to @user
else
render 'edit'
end
end
答案 1 :(得分:1)
我面临着和你一样的问题,但对我而言,我正在使用cancan设计。因此,在我的控制器中,我会把
before_filter :authenticate_user!, :except=>[:create]
除了创建之外,它将对用户进行身份验证。
def index
@user = User.all
authorize! :index, @user
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @user }
end
end
您想要授权用户访问的每个控制器功能,您可以这样做,似乎您必须通过将每个单独放在您需要授权的函数中而不是仅使用load_and_authorize_resource来执行大量工作,但希望可以帮助你完成我所做的一切。这是资源:https://github.com/ryanb/cancan/wiki/authorizing-controller-actions。如果您得到答案以及load_and_authorize_resource无法正常工作的原因,请发布到此处:)
答案 2 :(得分:1)
我(还)没有给出答案为什么会发生这种情况,但我遇到了同样的问题。我的情况不同之处在于手动授权每个操作(而不是依赖于“授权资源”或“load_and_authorize”)是关键。
答案 3 :(得分:1)
我也遇到了这个问题,这就是我找到的。
If I'm reading the source code right,在:update
操作期间,load_and_authorize
执行find_by
加载资源,然后在其上调用authorize!
。但是,在应用传入参数后,我看不到它授权的位置。 (如果我读错了,请有人纠正我。)
我看到的用例是当有人编辑资源时,在编辑中更新资源中的值,使其不再有资格在保存时传递授权。 (当然,我正在设置UI以帮助避免这种情况,但显然我仍然希望保护资源。)运行功能测试,我能够设置我希望不在控制器上传递授权的属性{{1动作,大概是因为检查发生在解析属性之前。
到目前为止,我处理它的方法是在设置属性后再次调用:update
,这意味着我无法使用authorize!
,因为我想在保存前进行授权:< / p>
update_attributes
另一种方法是创建一个before_filter,自己加载class FooController < ApplicationControlller
load_and_authorize_resource
def update
# slurp the mass assignable params
@foo.attributes = params[:foo]
# set some other params
@foo.some_other_attr = 'bar'
# authorize again, now that we have updated the params
authorize! :update, @foo
if @foo.save!
flash[:notice] = I18n.t(...)
respond_with(@foo)
# ...
end
end
end
实例,然后按上面的方式调用authorize,但这并没有让事情变得更清晰,恕我直言。它只会保存一个授权!调用
我很好奇其他人如何处理这件事。我对CanCan很新,所以我假设我做错了什么。 :)