如何将我的应用限制在单个浏览器标签中?

时间:2011-10-21 02:41:35

标签: php javascript session

坦率地说,它只是在v1.0中引起了太多的麻烦,因为它具有需要三个表单提交的功能,其中$_SESSION会话数据包含所有中间内容 - 只是让用户启动操作,然后打开第二个选项卡并执行第二个操作,该操作会遍历会话数据。

我怀疑这是恶意的(但不能打折)。用户更有可能启动操作,中断,忘记他们已启动或无法找到原始选项卡,因此再次启动(然后再找到原始选项卡并尝试再次完成操作)。

由于我在PHP编码,我可以检测表单提交时会话数据的存在(如果用户打开另一个选项卡,我将如何使用JS?我想我需要Ajax - 对吧?)。

所以,每次我开始一个操作时,我会在会话数据中检查一个标志,如果设置我重新加载到“对不起,戴夫。我恐怕我不能那样做“页面,否则我设置标志并继续(记住在操作结束时清除它)。

我想那可行,但是:
    1)将浏览器应用程序限制为单个选项卡/实例是否可以接受?     2)我应该尝试在v2.0中允许多个实例吗?

还有其他意见,帮助或建议吗?

5 个答案:

答案 0 :(得分:5)

更好的设计是避免在会话中存储用户交互状态。将它放在隐藏的表单字段或其他内容中,以便每个客户端请求都带有与之关联的状态。如果您担心用户篡改它,请使用HMAC来防止它,并且如果它包含用户不应该看到的内容,则可能加密它。

仅表明在标签之间共享 - 例如用户的登录标识或购物车之类的东西 - 应存储在会话中。

答案 1 :(得分:4)

最多可以在会话文件中保留“最后请求的页面”列表,并带有标志,指示如果用户是这些关键表单标志之一,则不应允许用户离开它。因此,如果您在form.php并且它是no-move-off,那么加载的任何新页面都应显示“中止或关闭窗口”选项。

您无法阻止用户打开其他标签/窗口,但您可以阻止他们在其他窗口/标签中移动到您网站的其他位置。

但是,请注意这是一个非常糟糕的用户体验。想象一下,如果亚马逊将您困在购物车页面中,并且从未让您进入另一页而无需实际购买。考虑更新代码以允许多个不同的窗口使用相同的表单。

答案 2 :(得分:2)

如果每个浏览器都支持选项卡式浏览,那么尝试将浏览限制为单个选项卡(那么您可能会创建一个桌面应用程序)将是一种糟糕的用户体验。

您可以解决此问题的一种方法是在表单中添加CSRF令牌(作为隐藏变量),并随请求一起提交。

CSRF reference

有许多方法可以生成令牌,但基本上是你:

  1. 创建令牌
  2. 存储在$_SESSION
  3. 使用<input type="hidden" name="{token name}" value="{token value}" />
  4. 输出表单

    然后当表单提交时,请检查$_REQUEST['{token name}'] == $_SESSION[ {token name}]`。

    如果该令牌不同,您知道它不是您最初生成的表单,因此可以忽略该请求,直到真实表单带有正确的令牌。

    有一件事:如果攻击者能够弄清楚如何生成CSRF令牌,那么他们就可以伪造请求。

答案 3 :(得分:2)

登录后添加以下脚本(例如dashboard.php)

patch

在其余页面的标题中添加了以下脚本 - &#39; random_value&#39;来自该用户的数据库

<script>
$(document).ready(function()
{
    $("a").attr("target", "");
    if(typeof(Storage)              !== "undefined") 
    {
        sessionStorage.pagecount    =   1;
        var randomVal               =   Math.floor((Math.random() * 10000000) + 1); 
        window.name                 =   randomVal;
        var url                     =   "url to update the value in db(say random_value)";
        $.post(url, function (data, url)
        {
        });
    } 
    else 
    {
        var url                     =   "url to remove random_value";           
        $.post(url, function (data, url)
        {
            sessionStorage.removeItem('pagecount');
            sessionStorage.clear();
            window.location         =   'logout.php';
        });
    }    
});
</script>

答案 4 :(得分:0)

如果我现在这样做,我可能会编写单页AngularJs应用程序(虽然任何形式的J都可以)。

启动时,在本地存储中查找标志。如果设置,拒绝启动,使用适当的消息,否则设置标志&amp;运行应用程序。

当然,恶意用户可以绕过它,因为它不是服务器端检查,但我会拒绝支持。