C# 防止在新选项卡中覆盖会话变量

C# 防止在新选项卡中覆盖会话变量,c#,asp.net,session,webforms,legacy-code,C#,Asp.net,Session,Webforms,Legacy Code,我继承了一个旧的ASP.NETWebForms应用程序,它大量使用会话变量来存储用户提交的应用程序的数据库记录ID。这导致了一些严重的问题,用户在多个选项卡中打开不同应用程序的表单,无意中用另一个应用程序的数据覆盖了一个应用程序中的信息 整个应用程序的常见用法如下所示: // Get the application ID from the database var appID = Convert.ToInt32(Session["appID"]); // Update application

我继承了一个旧的ASP.NETWebForms应用程序,它大量使用会话变量来存储用户提交的应用程序的数据库记录ID。这导致了一些严重的问题,用户在多个选项卡中打开不同应用程序的表单,无意中用另一个应用程序的数据覆盖了一个应用程序中的信息

整个应用程序的常见用法如下所示:

// Get the application ID from the database
var appID = Convert.ToInt32(Session["appID"]);

// Update application using the above ID
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);

// Redirect to another step of the form
Response.Redirect("/application/step-2");
this.ViewState["AppID"] = appID;
由于这个问题在应用程序的许多页面上都存在,所以我发现的解决方案并不理想(详细内容见本文末尾)

我的问题:有没有办法防止新选项卡覆盖现有会话变量,而不必重写整个应用程序的会话访问?

以下是我发现的解决方案,由于应用程序需要更改的程度,这些解决方案或多或少是最后的手段:

  • ViewState(“\u PageID”)
    前置到会话变量

  • 使用无cookieless会话(存储在URL中)


*上述解决方案已在相关帖子中找到:

从逻辑上讲,AppID不是会话的属性。它是页面的属性,也可能是工作流的属性

如果需要存储在回发之间持续存在的页面属性,可以按如下方式存储:

// Get the application ID from the database
var appID = Convert.ToInt32(Session["appID"]);

// Update application using the above ID
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);

// Redirect to another step of the form
Response.Redirect("/application/step-2");
this.ViewState["AppID"] = appID;
并执行更新

var appID = (int)ViewState["appID"]
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);
请务必确保安全,否则恶意用户可能会篡改AppID并更新其他人的记录


ViewState存储在页面本身中,因此不会在选项卡之间泄漏。

从逻辑上讲,AppID不是会话的属性。它是页面的属性,也可能是工作流的属性

如果需要存储在回发之间持续存在的页面属性,可以按如下方式存储:

// Get the application ID from the database
var appID = Convert.ToInt32(Session["appID"]);

// Update application using the above ID
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);

// Redirect to another step of the form
Response.Redirect("/application/step-2");
this.ViewState["AppID"] = appID;
并执行更新

var appID = (int)ViewState["appID"]
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);
请务必确保安全,否则恶意用户可能会篡改AppID并更新其他人的记录


ViewState存储在页面本身中,因此不会在选项卡之间泄漏。

听起来重写代码以将数据存储在会话之外的其他位置是不可行的

如果确实如此,那么最简单的选择可能是在用户在第二个选项卡中打开站点时,或者在其他选项卡中的活动修改AppID时,向站点添加代码以显示错误

完全防止多个选项卡 以下是一种方法,高级别:

  • 向应用程序_EndRequest添加代码,以输出一个“微会话”cookie,其中包含每个页面的时间戳或随机nonce。注意:您必须小心不要为资源请求(例如图像或CSS)输出此cookie。仅当当前请求用于页面时才输出

  • 在common.js文件中添加一小段javascript(或使其在站点中的每个页面上运行的任何位置),这将执行以下操作:

    a。在页面加载时,获取microsession cookie并将其值存储在Javascript变量中

    b。偶尔检查microsession cookie以查看它是否已更改。您可以使用计时器完成此操作,也可以在用户提交任何表单时进行检查。请注意,某些设备会在选项卡失去焦点时暂停脚本,因此如果使用计时器,还应检查选项卡何时再次获得焦点

    c。如果cookie已更改,则意味着用户从您的站点请求了一个页面,但该页面位于不同的选项卡中。显示错误。此时,您可以强制他们注销,也可以直接将他们重定向到主页,在主页上会自动为他们构建一个新的干净会话

  • 只要AppID不变,允许多个选项卡
    如果您希望允许多个选项卡,并且只想在AppID发生意外更改时导致错误,则可以将microsession cookie设置为AppID的哈希值,而不是nonce。这样,只有当AppID更改时才会触发错误。如果需要检查多个会话变量,可以在生成哈希之前将它们连接起来(字符串连接很好)。

    听起来重写代码以将数据存储在会话以外的其他位置是不可行的

    如果确实如此,那么最简单的选择可能是在用户在第二个选项卡中打开站点时,或者在其他选项卡中的活动修改AppID时,向站点添加代码以显示错误

    完全防止多个选项卡 以下是一种方法,高级别:

  • 向应用程序_EndRequest添加代码,以输出一个“微会话”cookie,其中包含每个页面的时间戳或随机nonce。注意:您必须小心不要为资源请求(例如图像或CSS)输出此cookie。仅当当前请求用于页面时才输出

  • 在common.js文件中添加一小段javascript(或使其在站点中的每个页面上运行的任何位置),这将执行以下操作:

    a。在页面加载时,获取microsession cookie并将其值存储在Javascript变量中

    b。偶尔检查microsession cookie以查看它是否已更改。您可以使用计时器完成此操作,也可以在用户提交任何表单时进行检查。请注意,某些设备会在选项卡失去焦点时暂停脚本,因此如果使用计时器,还应检查选项卡何时再次获得焦点

    c。如果cookie已更改,则意味着用户从您的站点请求了一个页面,但该页面位于不同的选项卡中。显示错误。此时,您可以强制他们注销,也可以直接将他们重定向到主页,在主页上会自动为他们构建一个新的干净会话

  • 只要AppID不变,允许多个选项卡 如果要允许多个选项卡,并且只想在AppID中发生意外更改时导致错误,则可以将microsession cookie设置为