【问题标题】:Pass data between refresh/reload (client side, without server side sessions)在刷新/重新加载之间传递数据(客户端,没有服务器端会话)
【发布时间】:2015-05-25 21:37:23
【问题描述】:

在单页应用程序中,我想在页面重新加载/刷新期间传递敏感数据。

由于数据是敏感数据,因此不应恢复,例如

  • 当用户离开域然后返回时
  • 当用户关闭用户代理并重新启动它时,恢复之前的会话

历史

  • thirdpartypage.com (移至此处时丢弃数据)
  • mypage.com
  • thirdpartypage.com (移至此处时丢弃数据)

我的方法是将其存储在sessionStorage

// On data generation/update
sessionStorage.setItem("data", "DATA");

// ...

// On load (reload)
var data = sessionStorage.getItem("data")

if (data) {
    // Initialize application with data
} else {
    // Start without
}

不幸的是,在sessionStorage 中,当从我的应用程序的域移动到外部域(以及来回移动到我的应用程序的域)时,数据仍然存在。

我也尝试将其存储在

  • window.name,虽然对于 Chrome 来说这是可以接受的(不会跨域持久化),但 Firefox 可以在其他域中访问数据(IE 未经测试)
  • 一个短暂的 cookie,但我认为此解决方案不安全

【问题讨论】:

  • 只是为了澄清一下,您是在防止来自同一台计算机的未经授权的访问,还是其他什么?
  • 是的 Schlaus,我主要想防止来自同一台计算机的未经授权的访问。想象一下,用户正在公共图书馆中使用此应用程序,并且马虎地导航到另一个域而不是注销。

标签: javascript security session reload


【解决方案1】:

如果您有一个在页面加载后填充的文本输入,则在刷新页面时,浏览器将使用之前的值重新填充该字段。如果用户离开页面并返回(不重新加载),该字段将不再重新填充。

所以你可以做的是将敏感信息放在隐藏的文本输入中并从那里获取它,只有当用户刷新页面时它才会在那里。

【讨论】:

  • 不错的实用方法。适用于 Firefox 38,不适用于 Chrome 42,IE 未经测试 (this is what I've tried)。我认为这种行为高度依赖于非标准化的用户代理特定功能(不是吗?),使得这种方法难以预测。
【解决方案2】:

这里有两个截然不同的问题需要考虑:

  1. 当用户在未注销的情况下离开该站点,然后其他人访问该站点并偶然发现前一个用户的数据时,敏感数据会留在计算机上。

  2. 可以访问同一台计算机的人正在积极尝试获取您的数据,并在浏览器的 sqlite 数据库中四处寻找。

对于第一种情况,以某种方式区分页面重新加载和新访问者就足够了。一旦您知道这一点,您就可以为新访问者擦除 sessionStorage。 document.referrer 会告诉您是否有人通过链接进入,但无法判断是否有人输入了地址或页面是否刚刚重新加载。也许结合一个短暂的 cookie,你可以想出一个可靠的策略。

第二种情况更棘手,我认为您必须考虑相关数据是否敏感,以至于有人会这样做。也有人可能会争辩说,用户也应该对保护他们的数据负有一定的责任。一种解决方案是将该数据加密存储在 sessionStorage 中,并在 window.onbeforeunload 中将密钥存储在一个短暂的 cookie 中。如果页面加载时cookie仍然存在,您可以解密数据并恢复会话,如果不存在,则清除存储。

我不确定您是否可以接受这些方法,但我不知道有更好的方法来实现这一点。这并不是说不存在。但是,如果您确实选择了加密方式,crypto-js 是我的 javascript 加密和散列的首选解决方案。

这是一个伪代码示例:

global var user

when page loads {
    encryptionKey = getEncryptionCookie()
    if encryptionKey is null {
        // No key found, this is a new user
        eraseSessionStorage()
        user = initNewSession()
    } else {
        // Cookie found
        data = decrypt(getFromStorage('user-data'), encryptionKey)
        if data is valid {
            user = restoreSession(data)
        } else {
            // Wrong key, either an anomaly or a hack attempt
            eraseSessionStorage()
            user = initNewSession()
        }
    }
    user.key = newEncryptionKey()

}

when user does something {
    user.data = getNewData()
    saveToStorage('user-data', encrypt(user.data, user.key))
}

// ie. window.onbeforeunload in JS
when user leaving {
    // the validity has to be long enough to last
    // through a refresh, but short enough so no one
    // can re-enter the site without the user noticing
    setEncryptionCookie(user.key, 10 seconds)
}

通过这种方式,数据永远不会以未加密的方式保存,因此即使有人设法从 sessionStorage 中获取它也是无用的,当然前提是您生成了安全密钥。也许使用鼠标位置作为随机函数的种子?

【讨论】:

  • Schlaus,当用户输入 URL 或通过后退/前进按钮导航时,document.referrer 为空,它仅由 hrefs 和 location 更改设置。
  • @try-catch-我终于知道了,这是我的答案。我将编辑一个更具体的建议。
猜你喜欢
  • 1970-01-01
  • 2012-07-05
  • 2012-08-01
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多