[javascript] Use basic authentication with jQuery and Ajax

I am trying to create a basic authentication through the browser, but I can't really get there.

If this script won't be here the browser authentication will take over, but I want to tell the browser that the user is about to make the authentication.

The address should be something like:

http://username:[email protected]/

I have a form:

<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>

And a script:

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!');
    }
});

This question is related to javascript jquery ajax authentication

The answer is


There are 3 ways to achieve this as shown below

Method 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 
  },
});

Method 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 
  },
});

Method 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 
  },
});

Use the jQuery ajaxSetup function, that can set up default values for all ajax requests.

$.ajaxSetup({
  headers: {
    'Authorization': "Basic XXXXX"
  }
});

JSONP does not work with basic authentication so the jQuery beforeSend callback won't work with JSONP/Script.

I managed to work around this limitation by adding the user and password to the request (e.g. user:[email protected]). This works with pretty much any browser except Internet Explorer where authentication through URLs is not supported (the call will simply not be executed).

See http://support.microsoft.com/kb/834489.


Let me show you and Apache alternative- IIS which is need it before start real JQuery Ajax authentication

If we have /secure/* path for example. We need to create web.config and to prohibited access. Only after before send applayed must be able to access it pages in /secure paths

<?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>

Or, simply use the headers property introduced in 1.5:

headers: {"Authorization": "Basic xxxx"}

Reference: jQuery Ajax API


According to SharkAlley answer it works with nginx too.

I was search for a solution to get data by jQuery from a server behind nginx and restricted by Base Auth. This works for me:

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;
    }
}

And the JavaScript code is:

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

Article that I find useful:

  1. This topic's answers
  2. http://enable-cors.org/server_nginx.html
  3. http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/

The examples above are a bit confusing, and this is probably the best way:

$.ajaxSetup({
  headers: {
    'Authorization': "Basic " + btoa(USERNAME + ":" + PASSWORD)
  }
});

I took the above from a combination of Rico and Yossi's answer.

The btoa function Base64 encodes a string.


As others have suggested, you can set the username and password directly in the Ajax call:

$.ajax({
  username: username,
  password: password,
  // ... other parameters.
});

OR use the headers property if you would rather not store your credentials in plain text:

$.ajax({
  headers: {"Authorization": "Basic xxxx"},
  // ... other parameters.
});

Whichever way you send it, the server has to be very polite. For Apache, your .htaccess file should look something like this:

<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

Explanation:

For some cross domain requests, the browser sends a preflight OPTIONS request that is missing your authentication headers. Wrap your authentication directives inside the LimitExcept tag to respond properly to the preflight.

Then send a few headers to tell the browser that it is allowed to authenticate, and the Access-Control-Allow-Origin to grant permission for the cross-site request.

In some cases, the * wildcard doesn't work as a value for Access-Control-Allow-Origin: You need to return the exact domain of the callee. Use SetEnvIf to capture this value.


Use the beforeSend callback to add a HTTP header with the authentication information like so:

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!'); 
    }
});

How things change in a year. In addition to the header attribute in place of xhr.setRequestHeader, current jQuery (1.7.2+) includes a username and password attribute with the $.ajax call.

$.ajax
({
  type: "GET",
  url: "index1.php",
  dataType: 'json',
  username: username,
  password: password,
  data: '{ "comment" }',
  success: function (){
    alert('Thanks for your comment!'); 
  }
});

EDIT from comments and other answers: To be clear - in order to preemptively send authentication without a 401 Unauthorized response, instead of setRequestHeader (pre -1.7) use 'headers':

$.ajax
({
  type: "GET",
  url: "index1.php",
  dataType: 'json',
  headers: {
    "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
  },
  data: '{ "comment" }',
  success: function (){
    alert('Thanks for your comment!'); 
  }
});

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to authentication

Set cookies for cross origin requests How Spring Security Filter Chain works What are the main differences between JWT and OAuth authentication? http post - how to send Authorization header? ASP.NET Core Web API Authentication Token based authentication in Web API without any user interface Custom Authentication in ASP.Net-Core Basic Authentication Using JavaScript Adding ASP.NET MVC5 Identity Authentication to an existing project LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1