4

假设用户正在浏览一个网站,然后执行一些更改数据库的操作(假设他们添加了评论)。然而,当实际添加评论的请求进来时,我们发现我们需要强制他们登录才能继续。

假设登录页面要求输入用户名和密码,并将用户重定向回他们在需要登录时访问的 URL。该重定向适用于仅具有 GET 参数的 URL,但如果请求最初包含一些 HTTP POST 数据,则该数据现在会丢失。

当涉及 HTTP POST 数据时,谁能推荐一种处理这种情况的方法?

显然,如果有必要,登录页面可以动态生成一个包含所有 POST 参数的表单来传递它们(虽然这看起来很乱),但即便如此,我也不知道登录页面有什么方法可以重定向用户到他们的预期页面,同时将 POST 数据保留在请求中。


编辑:我应该明确的一个额外限制 - 想象一下,在用户提交评论之前,我们不知道是否需要登录。例如,他们的 cookie 可能在他们加载表单和实际提交评论之间过期。

4

6 回答 6

11

这是 Ajax 技术可能有用的一个好地方。当用户单击提交按钮时,在客户端显示登录对话框并在实际提交页面之前与服务器进行验证。

我能想到的另一种方法是在主页本身的 DIV 标记中动态显示或隐藏登录控件。

于 2008-09-10T01:14:21.640 回答
3

您可能想 在自己实现之前调查 Django删除此功能的原因。这似乎不是 Django 特有的问题,而是另一个跨站点伪造攻击。

于 2008-09-10T02:47:53.273 回答
2

只需将 POST 中的所有必要数据存储在会话中,直到登录过程完成。或者在数据库中有某种临时表来存储然后检索它。显然这是伪代码,但是:

if ( !loggedIn ) {
    StorePostInSession();
    ShowLoginForm();
}

if ( postIsStored ) {
    RetrievePostFromSession();
}

或类似的规定。

于 2008-09-10T01:35:26.270 回答
2

2个选择:

  1. 从登录页面写出凌乱的表单,然后 JavaScript form.submit() 将其写入页面。
  2. 让登录页面本身 POST 到请求页面(使用以前的值),并让该页面的控制器执行登录验证。将此纳入您已经拥有的用于检测未登录用户的任何逻辑(框架因他们如何执行此操作而异)。在伪 MVC 中:

        CommentController {
           void AddComment() {
             if (!Request.User.IsAuthenticated && !AuthenticateUser()) {
                return;
             }
             // add comment to database
           }

           bool AuthenticateUser() {
             if (Request.Form["username"] == "") {
                // show login page
                foreach (Key key in Request.Form) {
                   // copy form values
                   ViewData.Form.Add("hidden", key, Request.Form[key]);
                }
                ViewData.Form.Action = Request.Url;

                ShowLoginView();
                return false;
              } else {
                 // validate login
                 return TryLogin(Request.Form["username"], Request.Form["password"]);
              } 
           }
        }
于 2008-09-10T02:08:17.610 回答
1

在他们提交的页面上收集数据,并将其存储在您的后端(数据库?),同时他们完成登录序列,在登录表单的页面上隐藏事务 ID 或类似内容。完成后,通过使用后端的事务 ID 查找将他们返回到他们要求的页面,并将他们发布的所有数据转储到表单中以再次预览,或者只运行该页面将运行的任何代码。

请注意,如果用户需要登录以发表评论但尚未登录,许多系统(例如博客)会通过使用与发表评论相同的登录字段来解决此问题。

于 2008-09-10T01:15:41.513 回答
1

我知道它说与语言无关,但为什么不利用您正在使用的服务器端语言提供的约定呢?如果是 Java,数据可以通过设置 Request 属性来持久化。您将使用控制器来处理表单,检测登录,然后转发。如果设置了属性,那么只需使用该数据预填充表单?

编辑:您也可以使用所指出的会话,但我很确定如果您在 Java 中使用前向返回登录页面,请求属性将持续存在。

于 2008-09-10T02:23:51.847 回答