In this chapter we looked at databases and how to access them using server-side JavaScript.
In Chapter 16 we saw how to create a logon screen that redirects the user to one page if her password is valid or asks her to re-enter the password if invalid. The logon name and password were set in the code. Create a database, which holds user names and corresponding passwords, and use this to validate the user. |
||||||||
A: | This is a modified version of my solution to Chapter 16, Question 1. We can reuse the SecureHome.asp page from Chapter 16 as the secure page to which the user is directed if her name and password is correct. We need to create a database of usernames and passwords, which I've called security.mdb, and a logon page, which I've called Ch17_LogOn.asp. Make sure the pages are saved in a directory under your web server, such as the virtual directory AWalkOnTheServerSide that we created in the chapter. The example only works if the pages are browsed on a server; the example does not work if the pages are loaded as normal files.
<%@ language = JavaScript %> <html> <head> <script language=JavaScript> function form1_onsubmit() { var form = document.form1; var returnValue = false; if (form.txtUsername.value == "") { alert("Please enter your username"); form.txtUsername.focus(); } else if (form.txtPassword.value == "") { alert("Please enter your password"); form.txtPassword.focus(); } else { returnValue = true; } return returnValue; } </script> </head> <body> <% if (Request.Form.Count != 0) { var userNameInDatabase; var userName = new String(Request.Form("txtUsername")).toLowerCase(); var password = new String(Request.Form("txtPassword")).toLowerCase(); var mySQL = "select UserName FROM User WHERE " + "UserName='" + userName + "' AND Password='" + password + "'"; var adoRecordset = Server.CreateObject("ADODB.Recordset") adoRecordset.Open(mySQL,"DSN=SecureUsersDSN"); if (adoRecordset.EOF == false ) { var userNameInDatabase = adoRecordset("Username").Value; userNameInDatabase = userNameInDatabase.toLowerCase(); if (userNameInDatabase == userName) { Response.Cookies("IsValid") = "Yes"; Response.Redirect("SecureHome.asp"); } else { Session("LogonTrys") = parseInt(Session("LogonTrys")) + 1; } } else { Session("LogonTrys") = parseInt(Session("LogonTrys")) + 1; } adoRecordset.Close(); adoRecordset = null; } var invalidTrys = Session("LogonTrys"); if (isNaN(invalidTrys)) { invalidTrys = 1; Session("LogonTrys") = invalidTrys; } else { invalidTrys = parseInt(invalidTrys); } if ( invalidTrys != 1 ) { Response.Write("<P><font color=red size=+2>" + "Sorry the username/password" + " you entered were invalid</font></P>") if ( invalidTrys <= 3) { Response.Write("<P><font color=black size=+2>" + "Please re-enter your details" + "</font></P>") } } if ( invalidTrys <= 3) { %> <P> To access this website please enter your username and password in the boxes below</P> <form action="CH17_LogOn.asp" method=post id=form1 name=form1 onsubmit="return form1_onsubmit()"> <P>Username : <input id=txtUsername name=txtUsername></P> <P>Password : <input id=txtPassword name=txtPassword type=password></P> <P><input id=reset1 name=reset1 type=reset value=Reset> <input id=submit1 name=submit1 type=submit value="Log On"> </P> </form> <% } %> </body> </html> Save this page as Ch17_LogOn.asp. We now need to create the Access database to store usernames and passwords. Call it Security.mdb and create one table called User with two fields, UserName and Password, as shown in the following. You can leave the fields' properties at their default values.
You'll need to enter some usernames and passwords into your database. Finally, you need to create an ODBC data source for your database called SecureUsersDSN. Now let's look at how the code works. At the very top of Ch17_LogOn.asp, we have the all-important language direction telling the server our server-side code is JavaScript.
<%@ language = JavaScript %>
Next we have a block of client-side script containing the function form1_onsubmit() that will be called by the form's onsubmit event handler. Its purpose is to check that values have been entered by the user in the username and password text boxes. If they are empty, we let the user know and prevent the form submission from going ahead by returning false from the function. Next, we come to some server-side script, starting with an if statement in which we check to see if this page has any form elements submitted to it. Why do this? Well, this page both provides the means for the user to enter her username and password, and does the checking of that username and password when the form is submitted. We'll see shortly that the form on this page submits to the same page. So we must check if the user has loaded this page by navigating to this page with her browser, in which case we don't need to check her security details, or if the page has been loaded due to the user submitting the form to have her security details checked. <% if (Request.Form.Count != 0) { If this page has been loaded by a form submission, it's because the user has pressed the Submit button and wants her logon details checked and then taken to the secure home page or given another chance to enter the details. The next bit of code carries out that task. var userNameInDatabase; var userName = new String(Request.Form("txtUsername")).toLowerCase(); var password = new String(Request.Form("txtPassword")).toLowerCase(); var mySQL = "select UserName FROM User WHERE " + "UserName='" + userName + "' AND Password='" + password + "'"; var adoRecordset = Server.CreateObject("ADODB.Recordset") adoRecordset.Open(mySQL,"DSN=SecureUsersDSN"); if (adoRecordset.EOF == false ) { var userNameInDatabase = adoRecordset("Username").Value; userNameInDatabase = userNameInDatabase.toLowerCase(); if (userNameInDatabase == userName) { Response.Cookies("IsValid") = "Yes"; Response.Redirect("SecureHome.asp"); } else { Session("LogonTrys") = parseInt(Session("LogonTrys")) + 1; } } else { Session("LogonTrys") = parseInt(Session("LogonTrys")) + 1; } adoRecordset.Close(); adoRecordset = null; } The preceding code first retrieves the username and password submitted by the user and converts them to lowercase. This is done so that the username and password are case insensitive, although we could leave this out if we wanted to make the username and password case sensitive. Then the code creates a string of SQL (mySQL) that selects the username from the database where there is a matching username and password. We create a Recordset object and use the SQL string to open this recordset with the results of the select query. We can then check that the recordset has records in it—by checking that it's not at the EOF (end of file) position—then we compare the username value returned with the username submitted from the form. If they match, we can be sure it's a valid user. If it is a valid user, we set a cookie and redirect the user to the securehome.asp page. If it is an invalid user, we add 1 to the session variable LogOnTrys in which we keep count of how many attempts the user has made to log in. If it's more than three, we don't give the user another chance—this helps to prevent malicious hackers from writing code that would submit millions of different password/username combinations to our form in the hope of getting one right. It's in the next bit of code that we actually use the LogOnTrys session variable. If this is the first time this session the user has been to the page, the variable will contain no value, so we give it the value 1. Then in the second if statement, we check to see if the number of attempts is not 1. If it's not 1, this is clearly not the first time this session the user has been to the page, and therefore she must have been returned here as a result of entering an invalid username or password. This being the case, we write out a message telling the user that she entered an invalid username/password. If she has gotten it wrong three or fewer times, we write out HTML asking her to try again. var invalidTrys = Session("LogonTrys"); if (isNaN(invalidTrys)) { invalidTrys = 1; Session("LogonTrys") = invalidTrys; } else { invalidTrys = parseInt(invalidTrys); } if ( invalidTrys != 1 ) { Response.Write("<P><font color=red size=+2>" + "Sorry the username/password" + " you entered were invalid</font></P>") if ( invalidTrys <= 3) { Response.Write("<P><font color=black size=+2>" + "Please re-enter your details" + "</font></P>") } } In the final part of the page, we use a server-side if statement to check that the number of logon attempts is three or less. If it is, the if statement allows the HTML to be written to the page displaying a form with text boxes for the user to attempt another logon. If this is beyond her third attempt, then no logon form appears in the browser, and the user doesn't get a fourth chance unless she closes her browser down and navigates back to the page. Note that the form's ACTION attribute is LogOn.asp, meaning that the form submits to itself. if ( invalidTrys <= 3) { %> <P> To access this website please enter your username and password in the boxes below</P> <form action="LogOn.asp" method=post id=form1 name=form1 onsubmit="return form1_onsubmit()"> <P>Username : <input id=txtUsername name=txtUsername></P> <P>Password : <input id=txtPassword name=txtPassword type=password></P> <P><input id=reset1 name=reset1 type=reset value=Reset> <input id=submit1 name=submit1 type=submit value="Log On"> </P> </form> <% } %> </body> </html> |