使用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非常重要)
答案 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;
}
}
要防止出现浏览器登录对话框,您必须确保用户和密码正确。