Found something useful? Don't forget to leave a comment!

Saturday, November 21, 2009

Better-looking HTTP Basic authentication with XmlHttpRequest

I’m sure everyone has encountered the good old browser username/password dialog on some website or another that uses HTTP authentication. While the built-in browser dialog works, it looks old-fashioned, somewhat out-of-place and would be unprofessional on a large-scale website. In almost any case, a form-based login hooked up to a backend like PHP/MySQL would be ideal, but this is not always an option. But thanks to a little JavaScript, HTTP Basic authentication can also be performed through a spiffy-looking form. Ease of integration is the main advantage – you can integrate the login form anywhere on your website. It works pretty well (see below on Firefox quirk).

So let’s get down to the nitty-gritty of setting this up. I will only be detailing the JavaScript and form code, but at the end you can find a nice, simple HTML page that integrates everything.

First, we construct the login form. Note that there is not actually a FORM element since nothing is being GETted or POSTed – we call the JavaScript function described later to process the input.

   1: <fieldset>

   2:     <legend><b>LOGIN</b></legend>

   3:     Username<br />

   4:     <input name="user" id="u" style="width: 10em" type="text" onkeypress="handleEnter(this, event)" /><br />

   5:     Password<br />

   6:     <input name="pass" id="p" style="width: 10em" type="password" onkeypress="handleEnter(this, event)"/><br />

   7:     <input name="submitBtn" type="submit" value="Enter" onclick="submitLogin()" /></fieldset>

Note the functionality of the submit button – it calls the submitLogin JavaScript function, described below. Also note the IDs of the username and password fields, u and p.

The heart of the login function is powered by a JavaScript XmlHttpRequest call. The implementation as described below works and has been test on IE7+, and versions of Firefox in recent memory. It should also function on Chrome and Safari (not tested).

The following code is XHTML-compliant and should be placed within the HEAD section of the HTML file.

   1: <script type="text/javascript">

   2: //<![CDATA[


   4: function submitLogin() {


   6: username = document.getElementById('u').value;

   7: password = document.getElementById('p').value;


   9: addr = "Main/";

  10: if (username.length == 0 || password.length == 0)

  11: { return false; }

  12: xmlhttp = new XMLHttpRequest();

  13:"HEAD", addr, false, username, password);

  14: xmlhttp.send();

  15: if (xmlhttp.status == 200)

  16: {

  17:     document.location = "Main/";

  18: }

  19: else

  20: {

  21:     alert(xmlhttp.status + ": Login failed. Check your credentials.");

  22: }

  23: return false;

  24: }


  26: //]]>

  27: </script>

How it works:

  • We grab the username and password from the page elements with IDs of ‘u’ and ‘p’, corresponding to the fields we constructed above.

  • ‘addr’ corresponds to the password-protected directory or resource we are trying to access.

  • If any of the fields are blank, do nothing.

  • Construct and activate the XmlHttpRequest object using a header-only call to the address, passing the credentials the user supplied.

  • If we get a 200 OK response from the server, take the user to the protected page.

  • If not, pop up an error. (On Firefox, an incorrect username/password will pop up the browser dialog. The user will not see the error until they click ‘Cancel’)

Enjoy your shiny new login form! This works great for light applications that do not require full-blown DB authentication but still need a more user-friendly solution. I am currently implementing this as a front page for my Windows HFS file server.

*Thanks to Leo Vildosola for his Windows Live Writer Code Snippet plugin!

No comments: