我是否需要在每个控制器操作中验证会话变量? (导轨)

时间:2012-08-24 05:42:35

标签: ruby-on-rails rest redirect controller

来自this question的后续内容。

在我的应用程序中,我有一个Task模型。多个页面可以链接到单个任务的“编辑”URL。例如,/tasks/1/edit链接到/tasks/1user/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]

1 个答案:

答案 0 :(得分:0)

简而言之,是的......

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

  1. 创建静态HTML页面
  2. 嵌入指向/ task / 1 / edit
  3. 的链接
  4. 在更新结束时,它会重定向回静态网页。
  5. 要解决这个问题,你应该做的是存储一个表示位置的会话变量(例如在你的UsersController中,做一个before_filter并设置session [:return_task_update_to] =:users)

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

    这样,您就不需要验证网址或做一些疯狂的事情。只需在会话中设置状态,然后重定向(如果存在)。