重新登录和HTTP基本身份验证

Web开发人员早就意识到登录和登录受HTTP Basic Authorization保护的站点的问题。尽管还有其他身份验证方法不会遇到此问题,但是基本授权通常仍然是最佳选择。该网络具有足够的材料来描述各种通用和特定的解决方案。但是,不幸的是,我发现它们全部都仅描述了部分解决方案,这些解决方案只能在一种浏览器中使用,而不能在另一种浏览器中使用。在猫之下,我给出了我对该问题研究的一般性最终结果

我马上要预约,因为我不是前端开发人员,也没有深入研究各种“品牌”和浏览器版本。仅在撰写本文时具有相关版本的主流。对于大多数Web任务而言,这就足够了。对于那些需要支持整个浏览器“ zoo”的开发人员而言,本文可能是一个很好的起点

,问题的实质是HTTP基本授权标准不提供日志记录。通常。当您进入受“基本授权”保护的页面时,浏览器本身将显示带有请求登录名/密码的窗口,并在成功登录后将其保存在其深处。然后,对该站点其他受保护页面的所有后续请求将自动使用Authorization标头中的这些值:
授权:基本bm9uZTpub25l
其中bm9uZTpub25l是base64编码的登录名/密码链接无:无(您的用户名和密码可能不同)

为了登录,您只需要在浏览器的最深处及其上重置旧的用户名/密码即可。录制新唱片的地方。这就是惊喜等待着我们的地方。由于没有标准规范此操作,因此每个浏览器都根据自己的理解进行操作。

更糟糕的是,由于登录名/密码请求窗口是它自己的浏览器窗口,该窗口已经仅响应HTTP页面标题,因此在对页面正文进行任何处理之前会弹出该窗口。也就是说,在接收到状态为401的服务器响应时执行某些javascript不起作用。在用户面前,此窗口会反复出现,并反复要求输入登录名/密码。

实际上,这一点很关键,因为对于几乎所有浏览器而言,注销的唯一方法是使用明显错误的登录名/密码向服务器发送请求,接收状态为401的服务器响应,然后重置浏览器的登录名/密码缓存。但是,如果同时浏览器不允许您处理响应401并继续为新用户进行登录过程,即使在读取HTTP标头并抛出您要输入的授权形式的阶段也要进行控制,那么您将无法使用它,已经是一个问题。这是通过引用还是XMLHttpRequest或提取的普通请求都没关系。浏览器仍在解析标头的阶段进行控制。

所以…

初始数据:


  1. 在单独的logout.html页面上,所有逻辑均位于javascript脚本中,部分内容在演示过程中给出
  2. 指定的网址-成功登录后要重定向的页面地址
  3. 指定了url401-始终返回HTTP 401错误(未经授权)的页面地址

// file logout.html
const url = new URL("http://mysite.com/");
const url401 = new URL("http://mysite.com/401");

IE浏览器


我们的产品不需要对此浏览器的支持,因此该解决方案我还没有亲自测试过。不过,根据Google的说法,有一个解决方案,它也许是所有方法中最简单,最优雅的。而且,我从未见过任何信息表明此针对Microsoft浏览器的解决方案已失去其相关性:

if (document.execCommand("ClearAuthenticationCache")) {
    window.location.assign(url);
}

在IE中,有一个ClearAuthenticationCache方法可以丢弃“那些非常深的肠”。简洁大方。并且没有与辅助页面401跳舞。我不知道此方法是否在Edge中有效。大概是。

如果该方法存在并且“有效”,则document.execCommand构造返回true。然后window.location.assign(URL)重定向用户以输入新的用户名和密码

Firefox(72.0.1)


在我们的任务范围内,这是最有问题的浏览器。对于他来说,仍然不存在完整的解决方案。在15到20年的时间里,开发人员团队的错误跟踪器一直挂着一个针对所指示问题的请求。但是“事情仍然存在。” 可以达到的最大值是曲线razlogin。

输入:
在通过XMLHttpRequest或获取请求收到401响应后,Firefox不会刷新密码缓存。只有通过常规请求,并在URL本身中输入登录名/密码。也就是说,类似
http:// //无:none@mysite.com/
编码:

else if (/firefox|iceweasel|fxios/i.test(window.navigator.userAgent)) {
    url.username = 'none';
    url.password = 'none';
    window.location.assign(url);
}

之后,用户会收到一个登录名/密码输入表单,无论您输入什么形式,都会一次又一次弹出。事实是输入的值不会覆盖URL中指定的登录名/密码值。也就是说,不是输入的值,而是一堆不输入的值:每次都不会有输入到服务器的值。要使用其他名称登录,用户必须单击“取消”,转到开始页面(http://mysite.com/),然后在此处输入新的登录名/密码。

歪?但是a,没有其他解决方案

谷歌浏览器(79.0.3945.88)


对于Chrome,提取方法效果很好。但是XMLHttpRequest不起作用(((((缓存未重置,并且不会发生日志记录。此外,我尝试将登录名/密码设置为open方法的参数并设置标头。

else if (/chrome/i.test(window.navigator.userAgent)) {
    fetch(url401, {
      credentials: 'include',
      headers: {
        'Authorization': 'Basic ' + btoa('none:none'),
        'X-Requested-With': 'XMLHttpRequest'
      }
    }).then(() => {
      window.location.assign(url);
    }).catch(err => console.error(err));
}

我们使用明显不正确的用户名/密码对页面401进行提取请求,我们从服务器收到401响应,浏览器刷新了其缓存。

重要!服务器不应返回WWW-Authenticate标头否则,浏览器将获得控制权,并且永远不会发生从页面401进行重定向。按照约定,如果在request中指定了X-Requested-With:XMLHttpRequest,则服务器不应返回此标头因此,X-Requested-With标头已添加到request中

Safari(12)


对于Safari,情况恰好相反:XMLHttpRequest有效,但fetch不起作用

else {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url401, true, 'none', 'none');
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xhr.onerror = function(err) {
      console.error(err);
    };
    xhr.onload = function () {
      window.location.assign(url);
    };
    xhr.send()
}

这些操作与Chrome中的操作相同,仅通过XMLHttpRequest才

适用于Safari 6+版本。早期版本有自己的错误。尤其是,例如在5.1版本中,每次重定向时,浏览器都会强制重新请求授权,这就是为什么重定向到最终页面的授权原则上不起作用的原因。在5.0之前的版本中,日志记录无效。

All Articles