You are here: irt.org | Articles | JavaScript | Password Protection | Intelligent Password Verification [ previous next ]
Published on: Friday 6th February 1998 By: Martin Webb
The vast majority of password protectors rely on the visitor knowing the name of the file, which is used as a password. However, if you get it wrong you get an error message saying file not found. The Intelligent Password Verifier uses a subtle approach, by first attempting to load an image file as the entered password, if the JavaScript detects that the image did not load, i.e. it was not found, then it displays a password invalid message.
Many JavaScript password routines rely on the fact that the filename of the file being protected is unknown to all except those who require access. To hide a file in a directory on the WWW, requires two steps:
The first item is upto yourselves. The second item requires the server to return a default page when the directory is accessed, for example in a browser requests the following URL on my web server: /articles/js062/ then the server will actually return one of several possible files: index.htm, index.htm, home.htm or home.htm. This may be different on your server, but most appear to at least return index.htm.
To ensure that a directory listing is not returned place an index.htm file in the directory to be protected. The following works well:
<BODY> <P>Not authorised to access this secure directory. <P>Press the browsers back button to return from whence you came. </BODY>
If, for example, we have a file called x1y2z3.htm, then the password for this file would be x1y2y3.
The answer to the FAQ "How do I password protect a page?" uses this simple password mechanism:
<SCRIPT LANGUAGE="JavaScript"><!-- function go() { window.location.href = "http://www.irt.org/articles/js062/" + document.formName.passwordName.value + '.htm'; return false; } //--></SCRIPT> <FORM NAME="formName" onSubmit="return go()"> Enter Password: <INPUT TYPE="password" NAME="passwordName" VALUE="" SIZE=8> </FORM>
However, if the password is incorrect, then the file will not be found and the server will return an ugly file not found error message.
The following source code, uses the password entered to attempt to load a .GIF image file. If the image is loaded then the password is correct and then the file is loaded, if the image is not loaded then the password is wrong, and an alert message is displayed to the visitor.
Note: Microsoft Internet Explorer 3.x does not support the JavaScript image object, therefore, although the following will work without failing, it will not intelligently trap incorrect passwords.
To enable this to work smoothly we require one blank image blank.gif, and one image per protected file, for example x1y2z3.gif. The images should be very small, preferably 1 pixel high by 1 pixel wide, and the same color as the background color of the password entry page.
Finally, you need the following JavaScript. It relies on the fact that for browsers that support the images object, we can replace the blank.gif image with the password image, using the testForIt() function. If the image is not loaded then the images onError event handler is invoked which is used to display an 'Incorrect password - please retype' error message using the failtIt() function.
If the image is loaded then the images onLoad event handler is invoked which is used to load the file using the loadIt() function.
If the browser does not support the images object then the password entered is assumed to be correct and an attempt to load the file is made again using the loadIt() function.
The request flag is set to false or true in various places to ensure that the loading of the initial blank.gif image does not trigger the loading of another file. The returning of false in the testForIt() function ensures that the form submission is always cancelled.
<html> <head> <script language="JavaScript"><!-- var request = false; function testForIt() { request = true; if (document.images) document.images["testImage"].src = document.logon.password.value + '.gif'; else loadIt(); return false; } function loadIt() { if (request) window.location.href = document.logon.password.value + '.htm'; request = false; } function failIt() { if (document.images) document.images["testImage"].src = 'blank.gif'; if (request) alert('Incorrect password - please retype'); document.logon.password.value = ''; request = false; } //--></script> </head> <body> <form name="logon" onSubmit="return testForIt()"> <img src="blank.gif" name="testImage" alt="." width="1" height="1" onLoad="loadIt()" onError="failIt()"> Password: <input type="password" name="password"> </form> </body> </html>
Now all of that may have been a bit confusing, especially where to locate all the bits and pieces, so to summarise:
The following would look like the typical contents of the directory containing a typical password protected document:
/mydirectory /mydirectory/index.htm /mydirectory/x1y2y3.gif /mydirectory/x1y2y3.htm /mydirectory/blank.gif
The index.htm page can either be the simple html used to stop people retrieving a directory listing, or it can be used as the page to hold the password JavaScript/Form page.
The password protected page is x1y2z3.htm - the password is x1y2z3.
The image x1y2z3.gif is used to successfully acknowledge the password x1y2z3. If any other password is used (other than x1y2z3 and blank then the incorrect password is trapped and our own error message displayed.
The balnk.gif id the initial image loaded by the password JavaScript/form page.
now the only way to access the page x1y2z3.htm is via the password JavaScript/form page (unless of course someone knows the password). You can either place this password JavaScript in the sam directory (possibly as index.htm, or in another location altogether - in which case you'll need to adapt the JavaScript source code so that it uses either correct relative URL's to the images and directory, or absolute URL's.
For example, the following amended code uses absolute URL's to enable you to access the working example on irt.org from any other site:
<html> <head> <script language="JavaScript"><!-- var request = false; function testForIt() { request = true; if (document.images) document.images["testImage"].src = '/articles/js062/' + document.logon.password.value + '.gif'; else loadIt(); return false; } function loadIt() { if (request) window.location.href = '/articles/js062/' + document.logon.password.value + '.htm'; request = false; } function failIt() { if (document.images) document.images["testImage"].src = '/articles/js062/blank.gif'; if (request) alert('Incorrect password - please retype'); document.logon.password.value = ''; request = false; } //--></script> </head> <body> <form name="logon" onSubmit="return testForIt()"> <img src="/articles/js062/blank.gif" name="testImage" alt="." width="1" height="1" onLoad="loadIt()" onError="failIt()"> Password: <input type="password" name="password"> </form> </body> </html>
Try this example: Password is x1y2z3.
Intelligent Password Verification #2