[英]Rails: How to prevent unauthorized access of controller update action
Hi I am new to rails and I am trying to figure out how to prevent unauthorized access to the update action of a controller. 嗨,我是Rails的新手,我试图弄清楚如何防止未经授权访问控制器的更新操作。
I know I could have a before_filer that kicks out people that arent logged in and I have redirect_to
in the edit
action, but I want a way to stop a user from editing an object that does not belong to them. 我知道我可以使用一个before_filer来踢出arent登录的用户,并且在
edit
操作中具有redirect_to
,但是我想要一种阻止用户编辑不属于他们的对象的方法。
Ex: A authorized user can simply change a job
object in my app, by directly sending a PUT
request with any job.id
as a parameter and change any field they want. 例如:授权用户可以通过直接发送带有任何
job.id
作为参数的PUT
请求并更改他们想要的任何字段来简单地在我的应用程序中更改job
对象。
Here is my controller: 这是我的控制器:
def update
@job = Job.find(params[:id])
@job.update_attributes(params[:job])
redirect_to jobs_path
end
To try and fix this problem I tried to check in the update
action if it the user was authorized and if they werent, i would redirect them to the index page. 为了尝试解决此问题,我尝试检查
update
操作是否已获得用户的授权,如果没有,则将其重定向到索引页面。
def update
@job = Job.find(params[:id])
if @job.user.id != current_login
redirect_to jobs_path
end
@job.update_attributes(params[:job])
redirect_to jobs_path
end
But when I try to do this, rails gives me an error saying I can only have one redirect in an action. 但是,当我尝试执行此操作时,Rails给我一个错误,说我只能在一个操作中进行一次重定向。
Well, the straightforward fix to your immediate problem is to use flow control to make sure that only one redirect_to
is ever reached on a single request, as many others have suggested. 好了,直接解决您当前问题的方法是使用流控制来确保在单个请求上仅达到一个
redirect_to
,就像许多其他建议一样。
However, that's not really how I'd solve your larger problem. 但是,这并不是我要解决的更大问题。
First, there are a lot of existing solutions for managing authorization, such as cancan or rolify . 首先,有许多用于管理授权的现有解决方案,例如cancan或rolify 。 I'd look into those.
我会调查一下。
Second, I'd use a before_filter
to block access, as you suggest. 其次,正如您所建议的,我将使用
before_filter
阻止访问。 Something like: 就像是:
before_filter :load_job, :only => [:show, :edit, :update, :delete]
before_filter :require_authorization, :only => [:edit, :update, :delete]
def load_job
@job = Job.find(params[:id])
end
def require_authorization
redirect_to jobs_path unless current_user.can_edit?(@job) # or whatever you want to check
end
The before filters will execute in order, so you'll already have the user & the job available when you check permissions, and can check permissions for that specific job. Before筛选器将按顺序执行,因此在检查权限时您已经具有可用的用户和作业,并且可以检查该特定作业的权限。
def update
@job = Job.find(params[:id])
@job.update_attributes(params[:job]) unless @job.user.id != current_login
redirect_to jobs_path
end
:) :)
This is probably because after the first redirect the second one could still be executed. 这可能是因为在第一次重定向之后,第二个仍然可以执行。 Thus putting the
update_attributes
and the second redirect
into the else path like this should solve the problem: 因此,像这样将
update_attributes
和第二个redirect
放入else路径应该可以解决问题:
def update
@job = Job.find(params[:id])
if @job.user.id != current_login
redirect_to jobs_path
else
@job.update_attributes(params[:job])
redirect_to jobs_path
end
end
You can either do redirect_to jobs_path and return
or return redirect_to jobs_path
. 您可以执行
redirect_to jobs_path and return
或return redirect_to jobs_path
。
Try the following: 请尝试以下操作:
def update
@job = Job.find(params[:id])
if @job.user.id != current_login
redirect_to jobs_path and return
end
@job.update_attributes(params[:job])
redirect_to jobs_path and return
end
The problem is that the redirect_to method doesn't end the current method; 问题是redirect_to方法没有结束当前方法; it just tells the controller to set some headers.
它只是告诉控制器设置一些标题。 In order to prevent this problem, you need to make sure that control doesn't "fall through" to the second redirect.
为了防止出现此问题,您需要确保控件不会“掉线”到第二个重定向。 One way to do this would be to put your alternative path into an else clause.
一种方法是将替代路径放入else子句中。 For example:
例如:
def update
@job = Job.find(params[:id])
if @job.user.id != current_login
redirect_to jobs_path
else
@job.update_attributes(params[:job])
redirect_to jobs_path
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.