0

这个问题的后续内容。

在我的应用程序中,我有一个任务模型。多个页面可以链接到单个任务的“编辑”网址。例如,/tasks/1/edit链接到 from/tasks/1user/1/(用户是另一个模型)。

在我的控制器中,我希望能够在通过“更新”操作提交“编辑”后重定向回任何一个引用页面。例如,如果我去/tasks/1/editfrom user/1/,在“更新”操作之后我想重定向回user/1/. 如果我去/tasks/1/editfrom ,同样的交易/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]在“更新”中验证吗?

4

1 回答 1

0

简而言之,是的……

request.referrer 存储将用户带到您的站点的 URL。如果您执行了以下操作:

  1. 创建静态 HTML 页面
  2. 嵌入指向 /task/1/edit 的链接
  3. 在更新结束时,它将重定向回静态网页。

为了解决这个问题,你应该做的是存储一个表示位置的会话变量(例如在你的用户控制器中,做一个 before_filter 并设置 session[:return_task_update_to] = :users)

然后,在更新结束时,您重定向回来,并清除会话中的 :return_task_update_to 变量。如果没有会话变量,您显然也会处理这种情况(在这种情况下,您将重定向到任何有意义的默认值)。

这样,您无需验证 URL 或做一些疯狂的事情。只需在会话中设置状态,如果存在则重定向。

于 2012-08-24T06:32:47.457 回答