Recently I needed a way for Threaded Tweets to do HTTP basic authentication to try out some stuff. As you probably know by now, it is written in javascript and uses no server side code. So, I had to find out some way to pass basic authentication credentials through the XMLHttpRequest object so that I could be authenticated with the Twitter server.

Turns out that it is pretty simple. If you use FireBug on any website that supports Basic Authentication, you will note that a new HTTP header called ‘Authorization’ is added. It looks like:

Authorization: Basic aDkdjfZy==

Now all you need to do is somehow pass on this header to the XMLHttpRequest object. If you use the native XMLHttpRequest, you can use the setRequestHeader method to do this:

xhr.setRequestHeader(“Authorization”, “Basic aDkdjfZy”);

What if you are using jQuery? Then also its pretty simple. jQuery’s AJAX object allows us to change the XHR object before the AJAX request is sent by setting the “beforeSend” callback; which is done as follows:

$.ajax ( {
url: “http://abc.com/”,
beforeSend: function (xhr) { xhr.setRequestHeader (“Authorization”, “Basic aDkdjfZy==”); },
succes: function(val) { alert(val); } } );

Base 64 Encoding:

One important part of Basic Authentication is that, you need to encode the username and password into Base 64. There are tons of Base 64 encoding tools written on javascript, which you can use. Example below:

xhr.setRequestHeader(“Authorization”, “Basic ” + encodeBase64 (“username:password”) );

That’s about it. Hope this was useful to you !

Some Updates

Cross-domain GET requests work all the time. The problem is with POST requests. Most browsers don’t allow XHR to POST data to a domain that’s different from the one in which the page is loaded. For this to work correctly, the ‘document.domain’ property must be set correctly.

The second best way to POST to another domain is to use an iframe and submit the form with the iframe as the “target”. Again, to read the result of the iframe, the “document.domain” of the parent and that of the iframe should match. This can be easily set through javascript. Thus, when the form post is done and the page is loaded, its value can be accessed.

Note: Chrome and Safari don’t allow access to iframe’s DOM if its document.domain is different from that of the iframe’s parent.

18 Responses to “HTTP Basic Authentication using AJAX”

  1. Donny V Says:

    This doesn’t work.

  2. Andy Cobian Says:

    Wouldn’t the login information be visible in the source code?

  3. Aswin Anand Says:

    @Andy: If you hard-code it in source code, yes, it will be visible. But you can get that as an input from the user.

  4. Kent Says:

    How about Digest Authentication?
    Have u ever try to implement Digest way, or it’s not possible yet?

  5. Aswin Anand Says:

    Hey Kent, digest authentication isn’t possible yet I believe.

  6. Adam Root Says:

    I am having a really hard time getting this to work. I am trying to build a form that updates my twitter through this. Can you post an example?

  7. Aswin Anand Says:

    Hey Adam, I’m unable to understand what you are trying to do. Can you be more clear?

  8. Phani Says:

    I’m trying to build a simple application to update twitter status. I tried a few different way including the one that you suggested:

    $.ajax({
    url: ‘http://twitter.com/statuses/update.json’,
    status: status,
    beforeSend: function(xhr) {xhr.setRequestHeader(“Authorization”, “Basic ” + Base64.encode(username + “:” + password))},
    sucess: function(result) {alert(‘done’ + result);}
    });

    But no matter which way I try, I’m getting the following error:

    “Access to restricted URI denied” code: “1012” on my error console. I did some research and is seemed like something to do with cross domain AJAX requests. But I’m wondering how it worked for you.

    Can you maybe post a working sample for updating twitter status?

  9. Aswin Anand Says:

    @Phani: I have updated the post. Please check the same.

  10. Phani Says:

    I tried setting the domain property to twitter.com. Still no luck though…

    document.domain=”twitter.com”;

    Any ideas on what I might be doing wrong?

  11. Aswin Anand Says:

    Try using an iframe to do an HTTP Post to twitter. Set the parent document’s domain to match that of twitter’s & you would be able to execute an onload when twitter returns its result.

  12. Robert Says:

    Has anyone actually got this working?

  13. Soumya SN Says:

    Hi Aswin,

    If you please add a snippet of code that you have written for cross domain basic authentication, it will be very helpful.

    I tried with the iframe concept, still not working for me 🙁

    Please help me out

  14. Tim Harper Says:

    I cleaned up the base 64 script and have posted it here:

    http://gist.github.com/300788

    Basically, I just extracted the JavaScript from the example, and then made all of the variables and helper methods private. I exposed the decoder/encoder functions as base64.encode, base64.decode

  15. Aswin Anand Says:

    Pretty cool Tim 🙂

  16. James Elford Says:

    I’m trying to get this working on my own bit of javascript; it’s running from a local file (and always will be), and I’m using the exact same code as Phani above, except I get 403 (authentication) errors. Any clues why? At the moment I’ve got my own username/password hardcoded in, and I’m pretty sure they’re correct!

    Thanks,

    James

  17. jQuery Ajax and REST HTTP Basic Authentication: done deal! | rassembling bits Says:

    […] the client-side, the basic idea (directly inspired by Aswin Anand’s solution) is to craft the Authorization request header in a beforeSend callback instead of relying on […]

  18. How to use Basic Auth and Jquery and Ajax | Easy jQuery | Free Popular Tips Tricks Plugins API Javascript and Themes Says:

    […] you have the complete example: http://www.aswinanand.com/2009/01/http-basic-authentication-using-ajax/ Tagged: ajax, authentication, jquery, questions /* * * CONFIGURATION […]