将特定于选项卡的数据绑定到HTTP GET请求

Gil*_*ili 12 html cookies ajax rest http

我正在尝试实现一种身份验证机制,其中每个浏览器选项卡可能以不同的用户身份登录.

以下是此系统的规则:

  • 身份验证令牌指示登录的用户.
  • 有两种身份验证令牌:私有和公共.
  • 每个私有令牌都绑定到一个选项卡并确定其帐户信息.
  • 可以通过任何选项卡读取/写入公共令牌,并指示登录的最后一个帐户(跨所有选项卡).
  • 当用户在任何选项卡中注销时,将删除私有和公共令牌.
  • 每次选项卡访问需要身份验证的页面时,系统都会尝试读取私有令牌.如果未设置(如新/空白选项卡的情况),则会尝试将公共令牌的值复制到私有令牌中.如果未设置公共令牌,则将用户重定向到验证屏幕.
  • 当选项卡已登录且用户单击链接时,该请求必须在自定义HTTP标头中包含私有标记.出于安全原因,不能在URI中发送此信息.
  • 能够使用后退/前进按钮进行导航,就像使用普通链接一样(意味着,没有提示重新提交表单数据).

到目前为止我尝试过的:

  • 使用cookies了私有和公共令牌:这不起作用,因为服务器无法知道看哪个饼干中如果用户点击从选项卡内的链接的方式,要求将所有的标签和所有的cookies服务器无法知道哪一个点击链接.

  • 存储私有令牌sessionStorage:这不起作用,因为当用户点击链接时,无法指定应与HTTP GET请求一起发送的自定义标头.

  • 使用AJAX请求页面,然后使用数据URI导航到内存中的页面:出于安全原因,Internet Explorer不允许对HTML内容使用DATA URI.请参阅http://msdn.microsoft.com/en-us/library/cc848897%28v=vs.85%29.aspx

  • 使用<form method="get" enctype="multipart/form-data">隐藏字段使用和传递令牌:enctype ="multipart/form-data"仅支持POST.

  • 使用<form method="post" enctype="multipart/form-data">隐藏字段并使用隐藏字段传递令牌:理论上,这应该可行但现在如果用户使用后退/前进按钮,则会提示用户重新提交表单数据.

  • 使用AJAX请求页面,然后使用重写当前页面document.open(); document.write(); document.close().我想这两个/sf/answers/308326161/http://forums.mozillazine.org/viewtopic.php?p=5767285&sid=d6a5a2e8e311598cdbad124e277e0f52#p5767285并在这两种情况下,在新的脚本<head>块永远不会执行.

有任何想法吗?

Gil*_*ili 14

好的,经过许多不同的迭代后,我们最终得到的实现是:

变量

  • 有两种数据存储:
  • 我们存储以下变量:
    • IndexedDB包含publicToken,nextTabId.
    • sessionStorage包含privateToken,tabId.

publicToken,privateToken

  • 有关身份验证令牌的定义,请参阅/sf/answers/111480071/.
  • 有两种身份验证令牌:公共令牌和私有令牌.
  • publicToken 是所有选项卡中上次登录操作返回的标记.
  • privateToken 是当前选项卡的上次登录操作返回的标记.

tabId

  • 每个选项卡由一个名为唯一标识的标记标识tabId.
  • nextTabId 是一个可在所有选项卡中访问的数字.
  • 如果选项卡没有id,它会根据nextTabId并创建一个新值,并递增其值.
  • 例如,tabId可以具有值"com.company.Tab X",其中X是返回的数字nextTabId.

登录/注销

  • 每次选项卡登录,privateTokenpublicToken使用由服务器返回的认证令牌将被覆盖.
  • 当用户注销时,我们删除privateTokenpublicToken在浏览器端和privateToken服务器端删除.我们不在publicToken服务器端删除.
  • 这意味着只要选项卡注销,所有共享相同选项卡的选项卡privateToken也会被注销.使用不同令牌的任何标签都不会受到影响.
  • 多个标签何时共享privateToken?在新窗口或选项卡中打开链接时,它将继承privateToken父选项卡.
  • 如果我们要publicToken在服务器上删除,则使用privateTokenX,publicTokenY 注销的选项卡将导致带有privateTokenY的选项卡被注销(这是不合需要的).

在页面加载

  • 扫描页面以查找HTML链接.
  • 对于每个链接,请将tabId查询参数附加到URL.参数值等于的值tabId.
  • 剥开tabId使用当前页的URL参数history.replaceState() ,因此用户可以与其好友分享链接(tabId用户固有的,不能共享).
  • 删除tabIdcookie(更多内容见下文).

单击链接时

  • 该选项卡创建一个tabIdcookie并跟随该链接.
  • cookie的名称等于值,tabId值等于值privateToken

当服务器收到请求时

  • 如果tabId参数丢失,然后重定向浏览器到GetTabId.html?referer=X哪里X是当前的URL.
  • 如果tabId存在但身份验证令牌无效或已过期,则将浏览器重定向到登录屏幕.

GetTabId.html

  • 如果选项卡没有privateToken,请复制publicTokenprivateToken.
  • 如果这两个privateTokenpublicToken是不确定的,重定向到登录页面.
  • 该页面采用一个名为URL的参数referer,该参数指示成功时重定向到的位置.
  • 如果选项卡有a privateToken,请将tabId参数附加到referer页面并重定向回页面.
  • window.location.replace()重定向时使用以GetTabId.html从浏览器历史记录中删除.

为什么我们继续删除/添加cookie?

  • 我们尝试最小化每个请求发送到服务器的cookie数量.
  • 如果我们没有tabId在页面加载时删除cookie,那么每次选项卡发出请求时,所有其他选项卡的cookie也会被发送.

已知的问题

  • "查看源代码"会打开缺少的网址tabId.结果,它获取重定向到GetTabId.html而不是实际页面的页面的源代码.
  • 笨拙的长页面重新加载(客户端被重定向到GetTabId.html原始页面并返回到原始页面).

为长期实施细节道歉,但我找不到更简单/更短的解决方案.