在解决超时会话后,如何通过 POST 请求重新提交表单?

发布于 2025-01-08 06:10:53 字数 1251 浏览 0 评论 0原文

让我看看是否可以解释这一点。

我的所有控制器中都有一个 before_filter :require_user

在我的 ApplicationController 中,我有以下方法

def require_user
  unless current_user #Redirect to login page if no user currently logged in
    flash[:notice] = "You must be logged in to access this page"
    redirect_to login_path
  end
  if current_user.timed_out? #Redirect to login page if user's session timed out and set session[:return_to]
    session[:user_id] = nil
    session[:return_to] = request.request_uri
    flash[:notice] = "Your session has timed out, please log back in"
    redirect_to login_path and return
  end
  current_user.update_last_request_at #Otherwise user is logged in. Update last request time in user model
end

然后,如果用户在超时后重新登录,我在 SessionsController 中使用以下方法重定向回用户想要的页面。

def redirect_back_or_default
  session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(root_path)
  session[:return_to] = nil
end

所有相当标准的东西 - 可能都是从railscasts或类似的地方复制的,我记不清了。

我遇到的问题是,当用户打开表单,然后会话在提交之前超时。当他们提交时,一个 POST 请求会发送到应用程序,before_filter 会拦截并要求他们重新登录。此时,由于 redirect_to(session[:return_to] 发送了 GET 请求,所以出现了问题)。有没有一种方法可以捕获请求方法(理想情况下还可以捕获表单参数),以便可以在会话中转发这些请求方法?

Let me see if I can explain this.

I have a before_filter :require_user in all of my controllers.

In my ApplicationController I have the following method

def require_user
  unless current_user #Redirect to login page if no user currently logged in
    flash[:notice] = "You must be logged in to access this page"
    redirect_to login_path
  end
  if current_user.timed_out? #Redirect to login page if user's session timed out and set session[:return_to]
    session[:user_id] = nil
    session[:return_to] = request.request_uri
    flash[:notice] = "Your session has timed out, please log back in"
    redirect_to login_path and return
  end
  current_user.update_last_request_at #Otherwise user is logged in. Update last request time in user model
end

Then I use the following method in my SessionsController to redirect back to the page the user wanted if they were logging back in after a time out.

def redirect_back_or_default
  session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(root_path)
  session[:return_to] = nil
end

All pretty standard stuff - probably all copied from railscasts or somewhere like that, I can't remember exactly.

The problem I have encountered is when a user brings up a form and then the session times out before they submit it. When they submit it, a POST request is sent to the app and the before_filter intercepts things and requires them to log back in. At this point things go wrong as a GET request is sent by the redirect_to(session[:return_to]). Is there a way of capturing the request method (and the form parameters ideally) so these can be forwarded in the session?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风情万种。 2025-01-15 06:10:53

要回答你的问题,你可以做到,但很痛苦。

session[:return_to] = {controller: params[:controller], action: params[:action], id: params[:id]}
session[:return_to_params] = parameters.inspect

然后让它们再次可用

eval(session[:return_to_params])

然后重定向并重新发布

redirect_to(params[:return_to].merge(eval(session[:return_to_params]))) 

您可以将其存储在数据库中、会话中、将其写入文件等中,从而使其变得尽可能复杂。


我想推荐一种替代方案

首先将您的提​​交更改为 ajax 请求。如果您担心您的表单在创建后不会重定向,只需让您的创建方法使用以下 javascript 进行响应:

window.location = "<%= destination %>"

然后将您的 require_user 修改为与此类似:

def require_user
  if current_user.nil? || current_user.timed_out?
    if request.xhr?
      render('ajax_login')
    else
      #what you were doing with your login requests
    end
  else
    current_user.update_last_request_at
  end
end

我在 Rails 2.3 上设置了它,但它很容易翻译。

基本上,如果他们提交 ajax 请求并注销,您将使用 javascript 进行响应,该 JavaScript 会创建一个带有登录屏幕的覆盖层。如果他们成功登录,您将删除覆盖层,他们可以再次单击“提交”(或者,如果您需要的话,您可以使用 javascript 自行提交)。

To answer your question you can do it, but its painful.

session[:return_to] = {controller: params[:controller], action: params[:action], id: params[:id]}
session[:return_to_params] = parameters.inspect

Then to get them usable again

eval(session[:return_to_params])

Then to redirect and re-issue

redirect_to(params[:return_to].merge(eval(session[:return_to_params]))) 

You can make this as complicated as you'd like from storing it in the DB, their session, writing it to a file, etc.


I'd like to recommend an alternative

First change your submission to be an ajax request. If your worried about your form not redirecting after create, just have your create method respond with javascript of:

window.location = "<%= destination %>"

Then modify your require_user to be similar to this:

def require_user
  if current_user.nil? || current_user.timed_out?
    if request.xhr?
      render('ajax_login')
    else
      #what you were doing with your login requests
    end
  else
    current_user.update_last_request_at
  end
end

I set this up on a rails 2.3 but its easy enough to translate over.

Basically if they submit an ajax request and are logged out, you respond with javascript which creates an overlay with a login screen. If they successfully sign in, you remove the overlay and they can click submit again (or you submit it yourself with javascript if that's what your looking for).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文