使用 jQuery 和 Ajax 进行基本身份验证
Posted
技术标签:
【中文标题】使用 jQuery 和 Ajax 进行基本身份验证【英文标题】:Use basic authentication with jQuery and Ajax 【发布时间】:2011-07-27 07:21:41 【问题描述】:我正在尝试通过浏览器创建基本身份验证,但我无法真正实现。
如果此脚本不在这里,浏览器身份验证将接管,但我想告诉浏览器用户即将进行身份验证。
地址应该是这样的:
http://username:password@server.in.local/
我有一个表格:
<form name="cookieform" id="login" method="post">
<input type="text" name="username" id="username" class="text"/>
<input type="password" name="password" id="password" class="text"/>
<input type="submit" name="sub" value="Submit" class="page"/>
</form>
还有一个脚本:
var username = $("input#username").val();
var password = $("input#password").val();
function make_base_auth(user, password)
var tok = user + ':' + password;
var hash = Base64.encode(tok);
return "Basic " + hash;
$.ajax
(
type: "GET",
url: "index1.php",
dataType: 'json',
async: false,
data: '"username": "' + username + '", "password" : "' + password + '"',
success: function ()
alert('Thanks for your comment!');
);
【问题讨论】:
所以您不希望浏览器处理 BASIC 身份验证?为什么不只使用基于表单的身份验证? @no.good.at.coding 如果您需要在身份验证之后与第三方 API 集成(这是我正在尝试做的 - developer.zendesk.com/rest_api/docs/core/…) 【参考方案1】:让我告诉你和 Apache 替代方案 - 在开始真正的 JQuery Ajax 身份验证之前需要它的 IIS
例如,如果我们有 /secure/* 路径。我们需要创建 web.config 并禁止访问。只有在发送之前应用后必须能够访问 /secure 路径中的页面
<?xml version="1.0"?>
<configuration>
<system.web>
<!-- Anonymous users are denied access to this folder (and its subfolders) -->
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
</authentication>
</security>
【讨论】:
【参考方案2】:一年的变化。除了代替 xhr.setRequestHeader
的 header 属性之外,当前的 jQuery (1.7.2+) 还包括一个带有 $.ajax
调用的用户名和密码属性。
$.ajax
(
type: "GET",
url: "index1.php",
dataType: 'json',
username: username,
password: password,
data: ' "comment" ',
success: function ()
alert('Thanks for your comment!');
);
从 cmets 和其他答案编辑:要清楚 - 为了在没有 401 Unauthorized
响应的情况下抢先发送身份验证,而不是 setRequestHeader
(-1.7 之前)使用 'headers'
:
$.ajax
(
type: "GET",
url: "index1.php",
dataType: 'json',
headers:
"Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
,
data: ' "comment" ',
success: function ()
alert('Thanks for your comment!');
);
【讨论】:
不应该是username
而不是user
吗?它也不完全相同:从在线文档和我的经验来看,它看起来不像某些 API 所要求的那样抢先。换句话说,它仅在返回代码 401 时才发送 Authorization
标头。
@StefanoFratini - 你在这两个方面都是正确的。修复了用户名字段,很高兴了解抢先式身份验证与仅在质询时响应。像其他答案一样明确设置标题将允许使用基本身份验证的这种“被动”变体。
对我来说,上面的选项不起作用,这就像一个魅力......谢谢
见上面的评论,请更正这个答案以表明 "Authorization": "Basic " + btoa("user:pass") 作为正确的标题
这就是我一直在寻找的答案!对我来说,这个答案的关键是如何使用“标头”来抢先发送身份验证。我的问题在这里得到了回答。 ***.com/questions/28404452/…【参考方案3】:
根据 SharkAlley 的回答,它也适用于 nginx。
我正在寻找一种解决方案,通过 jQuery 从 nginx 后面的服务器获取数据并受 Base Auth 限制。这对我有用:
server
server_name example.com;
location /
if ($request_method = OPTIONS )
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
# Not necessary
# add_header Access-Control-Allow-Credentials "true";
# add_header Content-Length 0;
# add_header Content-Type text/plain;
return 200;
auth_basic "Restricted";
auth_basic_user_file /var/.htpasswd;
proxy_pass http://127.0.0.1:8100;
javascript 代码是:
var auth = btoa('username:password');
$.ajax(
type: 'GET',
url: 'http://example.com',
headers:
"Authorization": "Basic " + auth
,
success : function(data)
,
);
我觉得有用的文章:
-
本主题的答案
http://enable-cors.org/server_nginx.html
http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/
【讨论】:
【参考方案4】:按照其他人的建议,可以直接在Ajax调用中设置用户名和密码:
$.ajax(
username: username,
password: password,
// ... other parameters.
);
或如果您不想以纯文本形式存储凭据,请使用 headers 属性:
$.ajax(
headers: "Authorization": "Basic xxxx",
// ... other parameters.
);
无论您以哪种方式发送,服务器都必须非常有礼貌。对于 Apache,您的 .htaccess 文件应如下所示:
<LimitExcept OPTIONS>
AuthUserFile /path/to/.htpasswd
AuthType Basic
AuthName "Whatever"
Require valid-user
</LimitExcept>
Header always set Access-Control-Allow-Headers Authorization
Header always set Access-Control-Allow-Credentials true
SetEnvIf Origin "^(.*?)$" origin_is=$0
Header always set Access-Control-Allow-Origin %origin_ise env=origin_is
说明:
对于某些跨域请求,浏览器会发送一个预检 OPTIONS 请求,该请求缺少您的身份验证标头。将您的身份验证指令包装在 LimitExcept 标记内,以正确响应预检。
然后发送一些headers告诉浏览器允许进行身份验证,Access-Control-Allow-Origin来授予跨站请求的权限。
在某些情况下,* 通配符不起作用作为 Access-Control-Allow-Origin 的值:您需要返回被调用者的确切域。使用 SetEnvIf 捕获此值。
【讨论】:
感谢浏览器发送不带身份验证标头的 CORS 预检请求的信息!像这样的细节可能会导致数小时的调试!【参考方案5】:上面的例子有点混乱,这可能是最好的方法:
$.ajaxSetup(
headers:
'Authorization': "Basic " + btoa(USERNAME + ":" + PASSWORD)
);
我从 Rico 和 Yossi 的回答中得到了上述内容。
btoa 函数 Base64 对字符串进行编码。
【讨论】:
这是个坏主意,因为您将使用 all AJAX 请求发送登录信息,而不管 URL 是什么。此外,$.ajaxSetup()
的文档说“为未来的 Ajax 请求设置默认值。不建议使用它。”【参考方案6】:
JSONP 不适用于基本身份验证,因此 jQuery beforeSend 回调不适用于 JSONP/Script。
我设法通过在请求中添加用户和密码来解决这个限制(例如 user:pw@domain.tld)。这适用于几乎所有不支持通过 URL 进行身份验证的浏览器除了 Internet Explorer(根本不会执行调用)。
见http://support.microsoft.com/kb/834489。
【讨论】:
猜测从安全角度来看,不允许这样做是明智的选择 链接已损坏 (404)。【参考方案7】:有3种方法可以实现,如下所示
方法一:
var uName="abc";
var passwrd="pqr";
$.ajax(
type: 'GET/POST',
url: 'urlpath',
headers:
"Authorization": "Basic " + btoa(uName+":"+passwrd);
,
success : function(data)
//Success block
,
error: function (xhr,ajaxOptions,throwError)
//Error block
,
);
方法二:
var uName="abc";
var passwrd="pqr";
$.ajax(
type: 'GET/POST',
url: 'urlpath',
beforeSend: function (xhr)
xhr.setRequestHeader('Authorization', "Basic " + btoa(uName+":"+passwrd));
,
success : function(data)
//Success block
,
error: function (xhr,ajaxOptions,throwError)
//Error block
,
);
方法三:
var uName="abc";
var passwrd="pqr";
$.ajax(
type: 'GET/POST',
url: 'urlpath',
username:uName,
password:passwrd,
success : function(data)
//Success block
,
error: function (xhr,ajaxOptions,throwError)
//Error block
,
);
【讨论】:
嗨,我已经测试了所有 3 种方法。但它从未产生 Authorization 标头。作为 dataType 我需要使用 jsonp 因为做跨域调用。并调用我没有机会更改的应用程序 API。直接从java http客户端它可以工作。但我无法通过 jquery 处理它。【参考方案8】:使用 jQuery 的 beforeSend
回调添加带有身份验证信息的 HTTP 标头:
beforeSend: function (xhr)
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
,
【讨论】:
我正在使用你提供的示例,但它不起作用` $.ajax ( url: "server.in.local/index.php", beforeSend: function (xhr) xhr.setRequestHeader("Authorization", “基本”+encodeBase64(“用户名:密码”));,成功:function(val)//alert(val);alert(“感谢您的评论!”);); `beforeSend: function(xhr) xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password)); ;
为我工作
问题...如果我通过的凭据失败,则在 Chrome 中,用户会看到一个对话框以再次输入用户名/密码。如果凭据失败,如何防止出现第二个对话框?
这不会将用户名和密码公开给任何人看吗?即使它在base64中,他们也可以对其进行解码。与下面的答案相同。
@calebB 基本身份验证通常只是将用户名和密码公开,任何人都可以看到。这不仅仅是这里描述的方法的问题。如果正在使用基本身份验证或真正的任何身份验证,则还应使用 SSL。【参考方案9】:
使用jQuery ajaxSetup函数,可以为所有ajax请求设置默认值。
$.ajaxSetup(
headers:
'Authorization': "Basic XXXXX"
);
【讨论】:
【参考方案10】:或者,直接使用 1.5 中引入的 headers 属性:
headers: "Authorization": "Basic xxxx"
参考:jQuery Ajax API
【讨论】:
【参考方案11】:使用beforeSend callback 添加带有身份验证信息的 HTTP 标头,如下所示:
var username = $("input#username").val();
var password = $("input#password").val();
function make_base_auth(user, password)
var tok = user + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
$.ajax
(
type: "GET",
url: "index1.php",
dataType: 'json',
async: false,
data: '',
beforeSend: function (xhr)
xhr.setRequestHeader('Authorization', make_base_auth(username, password));
,
success: function ()
alert('Thanks for your comment!');
);
【讨论】:
以上是关于使用 jQuery 和 Ajax 进行基本身份验证的主要内容,如果未能解决你的问题,请参考以下文章
使用 AJAX、JQuery、Apache 和基本身份验证的跨源请求
是否可以使用 jQuery 加密 AJAX 调用以进行身份验证?