Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMLHttpRequest based CORS call with Basic Auth fails in Firefox and Chrome

Need to make a REST GET call with Basic Auth from a javascript (in www.domain1.com). REST API is in domain2.com. REST API returns with the CORS specific HTTP headers. I need to support IE, Chrome and Firefox. Below JavaScript explains the issue further –

  1. Without Basic Auth (WORKS in IE 10, Chrome and Firefox, taking care of Older IEs by XDomainRequest object)

    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true);
    
  2. With Basic Auth (WORKS in IE 10 only, Fails in Chrome and Firefox)

    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true, username, password);
    
  3. With Basic Auth (Fails in Chrome and Firefox)

    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true);
    xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
    xhr. withCredentials = “true”;
    
  4. With Basic Auth (Fails in Chrome and Firefox)

    $.ajax({
    type: 'GET',
    url: jsonp_url,
    dataType: "json",
    username: username,
    password: pwd,
    beforeSend: function (xhr) {xhr.withCredentials = true; },
    success: function (result) { },
    error: function (xhr, ajaxOptions, thrownError) {
    }
    

    I would love to get a solution here that works in Chrome and FireFox with Basic Auth

like image 406
Andy T Avatar asked Oct 07 '13 21:10

Andy T


1 Answers

It got resolved. Noticed that the browser makes this cross domain calls with Authentication in 2 steps - a preflight call before the actual request. The nature of this preflight call is different in IE and [Chrome + Firefox]. IE makes a HTTP GET preflight call and it comes back with 401 and then it sends the authentication details in the actual request. But, Chrome and Firefox take much safer approach by making a HTTP OPTIONS call to check what all things the web server supports as CORS (Which domains are allowed / whether supports GET / POST etc) and the next call goes with the actual HTTP GET request with authentication.

Unfortunately, the API side was coded in such way that it was authenticating each Http call. That’s why even the HTTP OPTIONS call was also coming back with 401. [chrome + Firefox] were throwing exception right after the preflight call.

In the API side, modified the code not to return 401 in case of OPTIONS calls and it started working.

like image 52
Andy T Avatar answered Sep 25 '22 03:09

Andy T