来自this question的后续内容。
在我的应用程序中,我有一个Task模型。多个页面可以链接到单个任务的“编辑”URL。例如,/tasks/1/edit
链接到/tasks/1
和user/1/
(用户是另一个模型)。
在我的控制器中,我希望能够在通过“更新”操作提交“编辑”后重定向回任何一个引用页面。例如,如果我从/tasks/1/edit
转到user/1/
,则在“更新”操作后,我想重定向回user/1/
。如果我从/tasks/1/edit
转到/tasks/1
,那就相同了。
在我正在做的GET“编辑”操作中:
@task = Task.find(params[:id])
if request.referer and (request.referer == task_url(@task) or request.referer == user_url(@task.user))
session[:return_to] = request.referer
else
session.delete(:return_to)
end
在相应的PUT“更新”操作中,我这样做:
@task = Task.find(params[:id])
respond_to do |format|
if @task.update_attributes(params[:task])
format.html { redirect_to session.has_key?(:return_to) ? session[:return_to] : @task #return to task if no return_to specified
else
...
end
end
这很有效,但我担心客户端可以在“更新”中欺骗/伪造他们的session[:return_to]
,允许他们重定向到他们想要的任何页面。
这有关系吗?这是一个有效的问题吗?我是否需要在“更新”中验证session[:return_to]
?
答案 0 :(得分:0)
简而言之,是的......
request.referrer存储将用户带到您网站的网址。如果您执行了以下操作:
要解决这个问题,你应该做的是存储一个表示位置的会话变量(例如在你的UsersController中,做一个before_filter并设置session [:return_task_update_to] =:users)
然后,在更新结束时,您重定向回来,并清除会话中的:return_task_update_to变量。如果没有会话变量,你显然也会处理这种情况(在这种情况下你会重定向到默认的任何意义)。
这样,您就不需要验证网址或做一些疯狂的事情。只需在会话中设置状态,然后重定向(如果存在)。