如何结合localStorage和sessionStorage

时间:2015-08-03 16:30:48

标签: html5 authentication authorization local-storage session-storage

我想在浏览器标签之间共享我的身份验证令牌,建议使用HTML5 localStorage。但是,当浏览器关闭时,我不希望任何与身份验证相关的内容留在我的存储空间中,建议使用HTML5 sessionStorage

Reference 1 related to this topic (click)

  

这意味着您无法在标签之间共享,为此您应该使用localStorage

Reference 2 related to this topic (click)

  

因此,建议不要将任何敏感信息存储在本地存储中

如何在选项卡之间组合我的身份验证令牌,并确保在浏览器关闭时没有任何内容留在存储中?

其他网站如何解决这个看似简单的问题。

2 个答案:

答案 0 :(得分:5)

实现此目的的一个选项可能是在页面即将关闭/卸载时清除localStorage,因此在存储中不会留下任何内容。这样,localStorage的行为就像sessionStorage一样,一旦页面关闭就会删除它,但它仍然具有跨标签共享数据localStorage的优势

为此你可以使用onbeforeunload事件:

  

当窗口,文档及其资源即将卸载时会触发beforeunload事件。

这样的事情:

// code here
...

// you have the data in the localStorage
localStorage.setItem("data", "My Data");

// more code here
...

// when the page is about to be unloaded, remove the localStorage data
window.addEventListener("beforeunload", function() {
    localStorage.removeItem("data");
});

但是这个解决方案太简单了,而且有一个问题:当你关闭一个标签时,localStorage数据会被删除,即使你打开了其他标签! (留下他们没有任何数据)。为防止在其中一个选项卡关闭时删除数据,您可以跟踪选项卡的数量,并仅在数字为零时清除localStorage

伪代码将是:

  1. 页面加载:
    1. 如果localStorage有标签数
      1. 将标签数增加1
    2. 或者其他(没有标签数)
      1. localStorage中创建一个包含标签数量的变量。
      2. 将该变量设置为1(当前选项卡)。
  2. 页面卸载:
    1. 将标签数减少1。
    2. 如果标签计数为零(这是最后一个标签打开)
      1. 删除localStorage
      2. 的内容
  3. 这是一个非常简单的演示。我添加了一些console.log消息,因此您可以打开控制台并查看每次加载/卸载时发生的情况:

    <!doctype html>
    <html>
        <head>
            <title>Test LocalStorage</title>
        </head>
        <body>
            <h1>Hello World!</h1>
            <div id="tabs">Open tabs = 0</div>
            <script>
                window.addEventListener("load", function() {
                    if (!localStorage.tabs) {
                        console.log("Create the tab count");
                        localStorage.setItem("tabs", 1);
                        // restore data in case of refresh, or set to initial value in case of new window
                        localStorage.setItem("data", sessionStorage.getItem("data") || "Initial");
                    } else {
                        console.log("Add one tab to the count");
                        localStorage.tabs++;
                    }
    
                    document.getElementById("tabs").innerHTML = "Open tabs = " + localStorage.tabs;
                });
    
                window.addEventListener("beforeunload", function() {
                    if (parseInt(localStorage.tabs) == 1) {
                        console.log("Last tab: remove localStorage");
                        // save the data temporarily in the sessionStorage (in case of reload)
                        sessionStorage.setItem("data", localStorage.getItem("data")); 
                        localStorage.removeItem("tabs");
                        localStorage.removeItem("data");
                    } else {
                        console.log("There are more tabs open, decrease count by 1");
                        localStorage.tabs--;
                    }
                });
            </script>
        </body>
    </html>
    

    将该代码复制到一个页面中,并在几个选项卡中打开它,您将看到选项卡的数量增加(如果您重新加载其中一个打开的选项卡,则会更新)。然后关闭它们,并使用最后一个,&#34;数据&#34; <{1}}中的项目将被清除。

答案 1 :(得分:5)

我们使用Cookie。

存储有其用途。 但cookies符合您的所有要求。

  • Cookie在所有相同的原始标签中共享。您甚至可以指定其路径,但默认情况下它们是共享的。

  • 浏览器关闭后会自动删除Cookie,您无需执行任何操作;这也是默认行为。

  • 可以轻松地将Cookie设置为比存储更安全或更安全。

有时最好的解决方案是最简单的解决方案。 无需重新发明轮子。

Cookie安全

会话cookie存储在磁盘上,如sessionStorage(如果浏览器崩溃并需要恢复)。 因此,就本地磁盘读/写而言,它们同样安全。

在http传输期间,cookie和存储处理脚本都可能被获取甚至被盗 所以你必须在这两种情况下都使用HTTPS。 (这是你应该做的the least。)

Cookie可以配置为HTTP only, 阻止JavaScript访问它, 从而免受XSS scriptgreasemonkey hijacking的影响。

如果身份验证令牌被盗,我们还会将每个令牌与计算机的用户代理和IP相关联。 这可以防止令牌被外部网络使用。 如果需要,您可以添加更多content negotiation标题 - 并非所有机器人都会复制所有标题。

另一个安全级别,您可以添加client side fingerprinting。 这些指纹必须在客户端捕获并通过网络传输,因此它们不是防弹的, 但它们会迫使内部攻击者(与用户在同一网络上的攻击者)跳过另一个环。

此时,他们通常会切换到您无法控制的easier attacks