对父目录(同一领域)的HTTP基本认证请求在浏览器中工作,但不在AJAX中工作

时间:2014-06-23 02:44:09

标签: jquery ajax http-basic-authentication

使用HTTP基本身份验证时,我在父目录中使用jQuery ajax调用时遇到了一些奇怪的行为。

似乎有些事情在这里发生,我不明白,但我找不到一个好的参考资料来源,它给了我足够的细节,让我知道我是什么&#39我做错了。

任何人都可以指出我错过的内容,或者指出某些来源,这有助于我了解浏览器如何决定在Ajax请求上发送(或不发送)WWW-Authenticate标头?


我的设置如下所示。

Page: https://site.com/d1/d2/page.html (contains a jQuery ajax call to load 'Ajax')
Ajax: https://site.com/d3/some_resource.json

Both require the same HTTP Basic authentication (with the same realm)

走过我看到的行为......

请求' Page'在新的浏览器会话中,用户会遇到HTTP基本登录提示,如果他们提供了正确的详细信息,装了。

如果用户试图访问“Ajax”。直接在新的浏览器会话中,他们也受到HTTP基本登录的挑战,使用相同的领域。如果使用与上面相同的细节,则加载json内容。

在第一种情况下,我希望加载' Page成功应该允许Javascript代码在' Page'加载' Ajax',即使它在父目录中。

RFC 2617 - HTTP Authentication

  

领域值(区分大小写),与正在访问的服务器的规范根URL(abs_path为空的服务器的absoluteURI;参见[2]的第5.1.2节)相结合,定义了保护空间

相反,我看到的是ajax调用失败(401 Unauthorized)并通过Firefox控制台查看请求,它似乎没有“WWW-Authenticate'标题已发送。

然而 - 如果用户然后加载了#Ajax'直接在浏览器中,加载json内容(没有登录提示),以及随后对“页面”的请求。现在成功加载了#Ajax'资源。在这种情况下,我本来期望加载“Ajax”#39;直接在浏览器中没有任何影响。

(如果我使用Firefox 30.0和jQuery 1.10.2非常重要)

3 个答案:

答案 0 :(得分:3)

这里的问题似乎是身份验证不会随着jQuery发出的ajax请求一起发送,这可能很容易通过ajax调用上的xhrFields选项修复....通常,默认情况下它们会被发送你不是跨域工作。 (代理可能会导致这种情况。)

$.ajax({
   xhrFields: {
      withCredentials: true
   }
});

另一个问题可能是ajax调用不使用浏览器会话。要检查是否是这种情况,请查看jQuery发送的请求标头。在这种情况下,此答案中的链接可能会有所帮助:https://stackoverflow.com/a/7189502/1821215

答案 1 :(得分:1)

HTTP基本身份验证是基于质询/响应的身份验证协议;这就是为什么这个

  

在新的浏览器会话中请求“页面”时,用户是   使用HTTP基本登录提示

进行挑战

或发生这种情况

  

如果用户尝试直接在新的浏览器会话中访问“Ajax”   他们也受到HTTP基本登录的挑战

您可以在哪里提供凭据,如果凭据有效,您可以获得OK响应。

关于

  

我希望成功加载'Page'应该允许Javascript代码   在'Page'中加载'Ajax',即使它在父目录中。

即使你的页面加载成功,ajax调用也是对另一个资源的单独请求,这就是你得到这个响应的原因:

(来自RFC 2617 - HTTP身份验证第2页)

  

原始服务器使用401(未授权)响应消息   挑战用户代理的授权。这个回应必须   包括至少包含一个的WWW-Authenticate头字段   适用于所请求资源的挑战。

注意'WWW-Authenticate:'是服务器发送的响应头,它告诉用户代理验证方法和被访问的域。

(来自RFC 2617 - HTTP身份验证第3页)

  

希望使用来源对自身进行身份验证的用户代理   服务器 - 通常,但不一定,收到401后   (未经授权) - 可以通过包含Authorization标头字段来实现   请求。

在第4,5页,它说:

  

要获得授权,客户端会发送用户ID和密码,   由base64编码的单个冒号(“:”)字符分隔   凭据中的字符串。

     

如果用户代理希望发送用户标识“Aladdin”和密码   “打开芝麻”,它将使用以下标题字段:

  Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

希望这是有道理的。

建议的链接https://stackoverflow.com/a/5507289/463478可以帮助您进行ajax调用的身份验证。

答案 2 :(得分:0)

您可以使用此功能通过Ajax进行身份验证。在Opera和最古老的IE版本中,用户名和密码不能编码。

我使用这个库 https://github.com/ded/bowser 检测浏览器

function http_auth(user_verified, password)

    http = new XMLHttpRequest();
    if (bowser.opera || bowser.msie) {
        http.open("get", url, false, user_verified, password);
    } else {
        http.open("get", url, false, encodeURIComponent(user_verified), encodeURIComponent(password));
    }

    http.send("");
    if (http.status == 200) {
        return true
    } else {
        return false;
    }
}

要防止出现浏览器登录对话框,您必须确保用户和密码正确