【问题标题】:HTTP 401 - what's an appropriate WWW-Authenticate header value?HTTP 401 - 什么是合适的 WWW-Authenticate 标头值?
【发布时间】:2010-12-17 10:18:35
【问题描述】:

我目前正在处理的应用程序有一个会话超时值。如果用户没有交互的时​​间超过此值,他们尝试加载的下一页将提示他们登录。

发出的所有请求都通过此机制进行路由,其中​​包括 AJAX 调用。最初我们在登录页面中发送 200 标头,这引入了 AJAX 的一些问题,因为如果发送 200 响应,代码就会运行,并且从这些 RPC 调用发回的大多数数据是 JSON 或被评估的原始 JavaScript(不要问:|)。

我建议 401 更好,因为我们的 JSON 解析器不会尝试使用 HTML 登录页面.. :)

但是,当reading the spec 时,我注意到WWW-Authenticate 字段也必须发送。

这个字段有什么好的价值? Application Login 就够了吗?

【问题讨论】:

    标签: http-headers xmlhttprequest


    【解决方案1】:

    不,您必须指定要使用的身份验证方法(通常是“基本”)和身份验证领域。有关示例请求和响应,请参阅 http://en.wikipedia.org/wiki/Basic_access_authentication

    您可能还想阅读RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication

    【讨论】:

      【解决方案2】:

      当指示 HTTP 基本身份验证时,我们返回如下内容:

      WWW-Authenticate: Basic realm="myRealm"
      

      Basic 是方案,其余部分在很大程度上取决于该方案。在这种情况下,领域只是为浏览器提供了一个文字,当提示输入用户 ID 和密码时可以向用户显示。

      但是,您显然没有使用 Basic,因为使用 Basic Auth 时会话到期没有意义。我假设您正在使用某种形式的基于表单的身份验证。

      回想起来,Windows Challenge Response 使用了不同的方案和不同的参数。

      诀窍在于由浏览器决定它支持哪些方案以及如何响应它们。

      如果您使用基于表单的身份验证,我的直觉是保留 200 + 重新登录页面,但添加浏览器将忽略但您的 AJAX 可以识别的自定义标题。

      为了获得真正良好的用户 + AJAX 体验,让脚本挂起发现会话已过期的 AJAX 请求,通过弹出窗口触发重新登录请求,成功后,重新提交原始 AJAX 请求并继续正常。

      避免只是让脚本每 5 分钟访问一次站点以保持会话活动的作弊,因为这只是破坏了会话到期点。

      另一种选择是刻录 AJAX 请求,但这样的用户体验很差。

      【讨论】:

      • 谢谢伙计,我现在使用的是 403,因为它不是重定向,它实际上包含登录表单来代替原始页面。它也更符合 W3 规范。不过感谢您提供的信息。
      • 查看这个关于如何仍然使用 HTTP 401 的答案:stackoverflow.com/questions/928874/…
      • 是的,我想只要在 WWW-Authenticate 标头中添加任何内容即可。另一个类似的答案是stackoverflow.com/a/1088127/689161 或者只是违反规范并且不要费心发送标题(至少有几个网站这样做); 401 仍然比 403 更合适。
      • 我不确定我是否会在 WWW-Authenticate 标头中“放任何东西”,因为我无法确定请求是由我的 ajax 还是浏览器处理的。除了这个问题的标题,考虑到建议基于表单的身份验证的细节,我根本不会发送 WWW-Authenticate 标头。这是因为我没有要求浏览器参与身份验证/凭据质询。我只是希望它显示一个恰好是登录表单的表单,但是 ajax 可以用来识别它是一个登录表单,因此它可以像上面那样以不同的方式处理它。
      • 您应该制定一个身份验证方案以与标头一起使用。然后浏览器不会参与进来,因为它不会理解这个方案。如果您不包含标题,一些客户会感到不安或困惑。
      【解决方案3】:

      当用户会话超时时,我会发回一个 HTTP 204 状态代码。请注意,HTTP 204 状态不包含任何内容。在客户端我这样做:

      xhr.send(null);
      if (xhr.status == 204) 
          Reload();
      else 
          dropdown.innerHTML = xhr.responseText;
      

      这里是 Reload() 函数:

      function Reload() {
          var oForm = document.createElement("form");
          document.body.appendChild(oForm);
          oForm.submit();
          }
      

      【讨论】:

      猜你喜欢
      • 2016-06-02
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      • 2018-07-02
      相关资源
      最近更新 更多