使用jQuery和Ajax的基本身份验证

Pat*_*cow 403 javascript authentication ajax jquery

我试图通过浏览器创建基本身份验证,但我无法真正实现.

如果此脚本不在此处,则浏览器身份验证将接管,但我想告诉浏览器用户即将进行身份验证.

地址应该是这样的:

http://username:password@server.in.local/
Run Code Online (Sandbox Code Playgroud)

我有一个表格:

<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>
Run Code Online (Sandbox Code Playgroud)

还有一个脚本:

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!');
    }
});
Run Code Online (Sandbox Code Playgroud)

gga*_*ber 445

使用jQuery的beforeSend回调添加带有身份验证信息的HTTP标头:

beforeSend: function (xhr) {
    xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},
Run Code Online (Sandbox Code Playgroud)

  • `beforeSend:function(xhr){xhr.setRequestHeader("Authorization","Basic"+ btoa(username +":"+ password)); 对我有用 (68认同)
  • 问题...如果我通过的凭据失败,则在Chrome中会向用户显示再次输入用户名/密码的对话框.如果凭据失败,如何防止出现第二个对话框? (12认同)
  • 我正在使用你给的例子,但它不起作用`$ .ajax({url:"http://server.in.local/index.php",beforeSend:function(xhr){xhr.setRequestHeader("授权" ","Basic"+ encodeBase64("username:password"));},succes:function(val){// alert(val); alert("感谢您的评论!");}}); ` (6认同)
  • @calebB基本身份验证通常只保留用户名和密码,供任何人查看.这不仅仅是这里描述的方法的问题.如果使用基本身份验证或真正*任何*身份验证,则还应使用SSL. (6认同)
  • 这样是否会将用户名和密码公开开放给任何人查看?即使它在base64中,他们也可以对其进行解码。与下面的答案相同。 (2认同)

jma*_*g2k 336

一年中情况如何变化.除了header属性代替之外xhr.setRequestHeader,当前的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!'); 
  }
});
Run Code Online (Sandbox Code Playgroud)

从评论和其他答案编辑:要明确 - 为了抢先发送没有401 Unauthorized响应的身份验证,而不是setRequestHeader(pre -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!'); 
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 不应该是`用户名'而不是'用户'?它也不完全相同:从在线docos和我的经验来看,它看起来并不像某些API那样是先发制人的.换句话说,只有在返回代码401时才会发送`Authorization`标头. (15认同)
  • @StefanoFratini - 你在两方面都是对的.修复了用户名字段,了解抢占式auth vs仅响应挑战是很好的.像在其他答案中一样明确地设置标题将允许使用基本身份验证的这种"被动"变体. (3认同)
  • 这就是我一直在寻找的答案!这个答案对我来说的关键是如何使用'标题'来抢先发送身份验证.我的问题在这里得到了回答.http://stackoverflow.com/questions/28404452/phonegap-ios-ajax-request-never-completes (2认同)

Adr*_*man 62

使用beforeSend回调添加带有身份验证信息的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!'); 
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 您应该注意到,在少于10的IE版本和某些移动平台中,不支持此处用于Base64加密的"btoa" (4认同)

Ase*_*hwi 40

或者,只需使用1.5中引入的headers属性:

headers: {"Authorization": "Basic xxxx"}
Run Code Online (Sandbox Code Playgroud)

参考:jQuery Ajax API


Pau*_*eon 31

上面的例子有点令人困惑,这可能是最好的方法:

$.ajaxSetup({
  headers: {
    'Authorization': "Basic " + btoa(USERNAME + ":" + PASSWORD)
  }
});
Run Code Online (Sandbox Code Playgroud)

我从Rico和Yossi的回答中得到了上述结果.

BTOA功能的Base64编码字符串.

  • 这是一个坏主意,因为无论URL如何,您都将使用*all*AJAX请求发送登录信息.另外,`$ .ajaxSetup()`的文档说"为未来的Ajax请求设置默认值.**不建议使用它.**" (5认同)

Sha*_*ley 27

正如其他人所建议的那样,您可以直接在Ajax调用中设置用户名和密码:

$.ajax({
  username: username,
  password: password,
  // ... other parameters.
});
Run Code Online (Sandbox Code Playgroud)

用头财产,如果你宁愿不明文存储您的凭据:

$.ajax({
  headers: {"Authorization": "Basic xxxx"},
  // ... other parameters.
});
Run Code Online (Sandbox Code Playgroud)

无论你发送哪种方式,服务器都必须非常有礼貌.对于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_is}e env=origin_is
Run Code Online (Sandbox Code Playgroud)

说明:

对于某些跨域请求,浏览器会发送缺少您的身份验证标头的预检OPTIONS请求.将您的身份验证指令包含在LimitExcept标记内,以正确响应预检.

然后发送一些标头告诉浏览器允许它进行身份验证,并发送 Access-Control-Allow-Origin以授予跨站点请求的权限.

在某些情况下,*通配符不能用作Access-Control-Allow-Origin的值:您需要返回被调用者的确切域.使用SetEnvIf捕获此值.

  • 感谢浏览器在没有auth标头的情况下发送CORS预检请求的信息!像这样的细节会导致数小时的调试! (5认同)

Yos*_*sho 23

使用jQuery ajaxSetup函数,该函数可以为所有ajax请求设置默认值.

$.ajaxSetup({
  headers: {
    'Authorization': "Basic XXXXX"
  }
});
Run Code Online (Sandbox Code Playgroud)


小智 11

JSONP不能与基本身份验证一起使用,因此jQuery beforeSend回调将无法与JSONP/Script一起使用.

我设法通过向请求添加用户和密码来解决此限制(例如,用户:pw@domain.tld).这适用于除Internet Explorer之外的任何浏览,其中不支持通过URL进行身份验证(不会执行调用).

请参见http://support.microsoft.com/kb/834489.


Max*_*Max 8

根据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;
    }
}
Run Code Online (Sandbox Code Playgroud)

JavaScript代码是:

var auth = btoa('username:password');
$.ajax({
    type: 'GET',
    url: 'http://example.com',
    headers: {
        "Authorization": "Basic " + auth
    },
    success : function(data) {
    },
});
Run Code Online (Sandbox Code Playgroud)

我觉得有用的文章:

  1. 这个主题的答案
  2. http://enable-cors.org/server_nginx.html
  3. http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/


GSB*_*GSB 7

有三种方法可以实现这一点,如下所示

方法1:

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 
  },
});
Run Code Online (Sandbox Code Playgroud)

方法2:

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 
  },
});
Run Code Online (Sandbox Code Playgroud)

方法3:

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 
  },
});
Run Code Online (Sandbox Code Playgroud)