关于不可知的语言:当请求被登录页面中断时保留HTTP POST数据

关于不可知的语言:当请求被登录页面中断时保留HTTP POST数据

Retaining HTTP POST data when a request is interrupted by a login page

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

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

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

显然,如果需要的话,登录页面可以动态生成带有所有POST参数的表单以将其传递(尽管看起来很混乱),但是即使如此,登录页面仍无法以任何方式重定向用户到其预期的页面,同时将POST数据保留在请求中。

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


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

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


您可能想调查为什么Django在自己实现之前删除了此功能。这似乎不是特定于Django的问题,而是另一种跨站点伪造攻击。


2个选择:

  • 从登录页面写出凌乱的表单,然后将JavaScript form.submit()写入页面。
  • 让登录页面本身POST到请求页面(带有先前的值),并让该页面的控制器执行登录验证。将其应用到您已经具有的用于检测未登录用户的任何逻辑中(框架会因其执行方式而异)。在伪MVC中:
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
            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"]);
                  }
               }
            }

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

    1
    2
    3
    4
    5
    6
    7
    8
    if ( !loggedIn ) {
        StorePostInSession();
        ShowLoginForm();
    }

    if ( postIsStored ) {
        RetrievePostFromSession();
    }

    或类似的规定。


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

    编辑:您还可以使用所指出的Session,但是我很确定,如果您使用Java中的Forward返回登录页面,则Request属性将保持不变。


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

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


    推荐阅读

      linux命令是什么语言?

      linux命令是什么语言?,系统,环境,代码,传播,管理,语言,操作系统,源码,自由,

      linux数据库查找命令?

      linux数据库查找命令?,位置,名称,状态,服务,软件,信息,系统,命令,名字,密码,

      linux数据库同步命令?

      linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

      命令查看linux中断?

      命令查看linux中断?,网络,系统,状态,管理,地址,进程,命令,数据,信息,基础,Lin

      linux改语言命令行?

      linux改语言命令行?,系统,环境,工具,密码,概念,地方,软件,通信,管理,国际,lin

      linux命令行c语言?

      linux命令行c语言?,代码,系统,工具,环境,工作,保险,发行,命令,文件,终端,linu

      c语言在linux命令?

      c语言在linux命令?,系统,工作,管理,命令,保险,基础,环境,信息,文件,语言,linu

      linux建立数据库命令?

      linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

      linux命令进数据库?

      linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

      linux清空表数据命令?

      linux清空表数据命令?,系统,数据,软件,名称,不了,命令,文件,电脑,地址,位置,L

      linux拷贝数据命令?

      linux拷贝数据命令?,系统,地址,文件,数据,命令,目录,服务,基本知识,项目,密

      linux编写c语言命令?

      linux编写c语言命令?,系统,基础,环境,代码,盘面,保险,百度,情况,数据,工具,在

      linux中断程序命令?

      linux中断程序命令?,系统,管理,软件,传播,进程,命令,名称,程序,终端,指令,lin

      linux数据库检查命令?

      linux数据库检查命令?,服务,状态,地址,位置,系统,信息,命令,工作,情况,密码,

      linux命令进去数据库?

      linux命令进去数据库?,地址,服务,名字,系统,数据库,工具,基础,工作,管理,网

      linux数据库基础命令?

      linux数据库基础命令?,地址,工作,基础,系统,命令,信息,情况,工具,设备,目录,l

      linux的中断命令行?

      linux的中断命令行?,系统,暂停,状态,命令,管理,数字,传播,进程,终端,后台,lin

      linux数据共享命令?

      linux数据共享命令?,情况,系统,工具,网络,数据,软件,发行,设备,命令,文件,Lin

      linux进程中断命令行?

      linux进程中断命令行?,系统,软件,管理,进程,信息,名字,名称,平台,命令,结束,l

      linux终端中断命令?

      linux终端中断命令?,系统,名称,进程,管理,命令,信息,代码,工具,状态,程序,Lin