| << 15.3.1- The Home Page | Chapter15 | 15.3.3- Managing Items for Sale >> |
User Registration and Login
So, our user arrives at the site and is presented with Default.asp, which offers three options:
- They can choose to browse the sale items list (by choosing the Browse the listings hyperlink).
- If they're a first-time user, they can register with the system (by selecting the I'm a New User hyperlink).
- If they've visited the site before, they can use their email/password combination to log on to the system (by selecting Login hyperlink).
We'll cover the browsing option later in the chapter; in this section, we'll focus in on registration and login.
Collecting Registration Details
In order to allow a new user to register for the first time, we'll need to collect the user's personal details, check their password, and enter all the information into the database. In order to manage this, we'll create two new pages:
- Register.asp will be responsible for collecting the data from the user
- AddUser.asp will take that data and add it to thedatabase, and then pass the user on to MenuForRegisteredUsers.asp
In fact, the process of collecting a new user's details and adding them to the database is not very different from the processes needed to allow an existing user to edit their registration details. Therefore, we'll design Register.asp and AddUser.asp so that they are able to handle both tasks.
We'll see this arrangement unfold as we take a look at the code, in the following pages. First, let's write Register.asp.
Try It Out – Collecting Registration Details with Register.asp
1. Create a new ASP file, containing the following code. You may notice a section of JavaScript at the beginning of this code – we'll discuss this in a moment. In the meantime, don't forget that JavaScript is case-sensitive:
<BASEFONT FACE="Comic Sans MS" COLOR="DarkBlue">
<HTML>
<HEAD>
<SCRIPT language="JavaScript">
<!--
function VerifyData()
{
if (document.frmUser.Password.value != document.frmUser.VerifyPassword.value)
{
alert ("Your passwords do not match - please reenter");
return false;
}
else
return true;
}
-->
</SCRIPT>
<TITLE>Wrox Classifieds - User Registration</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFF80">
<CENTER>
<%
If Request("Update") = "True" Then
Response.Write "<H1>Wrox Classifieds<BR> Update User Registration</H1>"
Else
Response.Write "<H1>Wrox Classifieds<BR> New User Registration</H1>"
End If
%>
</CENTER>
<P>
<%
If Request("Update") = "True" Then
Response.Write "Please change your registration information as listed below<P>"
Else
If Request("NotFound") = "True" Then
Response.Write "<I>We were unable to locate your information. " & _
"Please take the time to register again.</I><P>"
Else
Response.Write "<CENTER>(If you're already registered with us, " & _
"then click the 'Login' link below.)</CENTER><P>"
End If
Response.Write "You only need to register with our system if you want to " & _
"bid on existing 'for-sale' items, or sell your own items " & _
"on these pages. <BR> " & _
"In order to use these services, please take a few minutes " & _
"to complete the form below. Once you have done that, " & _
"you will have full access to the system."
End If
%>
<FORM ACTION="AddUser.asp" NAME="frmUser" METHOD="POST"
onSubmit="return VerifyData()">
<TABLE BORDER=0>
<TR>
<TD WIDTH=20% ROWSPAN=11> </TD>
<TD>E-Mail Address:</TD>
<TD><INPUT TYPE="Text" NAME="email" VALUE="<%= Session("EMailAddress")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Given Name:</TD>
<TD><INPUT TYPE="Text" NAME="GivenName" VALUE="<%= Session("GivenName")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Family Name:</TD>
<TD><INPUT TYPE="Text" NAME="FamilyName" VALUE="<%= Session("FamilyName")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Address:</TD>
<TD><INPUT TYPE="Text" NAME="Address1" VALUE="<%= Session("StreetAddress1")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD></TD>
<TD><INPUT TYPE="Text" NAME="Address2" VALUE="<%= Session("StreetAddress2")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>City:</TD>
<TD><INPUT TYPE="Text" NAME="City" VALUE="<%= Session("City")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>State:</TD>
<TD><INPUT TYPE="Text" NAME="State" VALUE="<%= Session("State")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Postal Code:</TD>
<TD><INPUT TYPE="Text" NAME="PostalCode" VALUE="<%= Session("PostalCode")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Country:</TD>
<TD><INPUT TYPE="Text" NAME="Country" VALUE="<%= Session("Country")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD> <P>Password:</TD>
<TD VALIGN=bottom><INPUT TYPE="Password" NAME="Password"
VALUE="<%= Session("Password") %>" SIZE="40"></TD>
</TR>
<TR>
<TD>Verify Password:</TD>
<TD><INPUT TYPE="Password" NAME="VerifyPassword" SIZE="40"></TD>
</TR>
<TR>
<TD></TD>
<TD ALIGN=CENTER COLSPAN=2><BR>
<INPUT TYPE="Submit" VALUE="Submit Registration">
<INPUT TYPE="RESET"></TD>
</TR>
</TABLE>
</FORM>
<HR>
<TABLE BORDER=0 WIDTH=100%>
<TR ALIGN=CENTER>
<TD WIDTH=33%><A href="BrowseListings.asp">Browse the listings</A></TD>
<TD WIDTH=33%><A href="Login.asp">Login</A></TD>
<TD WIDTH=33%>I'm a new user</TD>
</TR>
</TABLE>
</BODY>
</HTML>
2. Save the file as Register.asp, in the same folder as you placed Default.asp.
3. From the home page, click on the I'm a new user hyperlink to view the registration page. Add some registration details, but don't press the Submit button – we haven't added the page to handle that yet.
|
|
How It Works
There seems to be quite a lot of code here, but it's not too difficult. The main task of Register.asp is to present the user with a form, which they will use to submit their registration information. When the user has completed the form, they press the
Submit Registration button. At this stage, a client-side script is executed to parse the values of the Password and Verify Password fields (to make sure they match). If this brief check is successful, contents of the form are submitted to AddUser.asp – which will perform the database updates, as we'll see shortly. Once that script has completed, the user will be automatically redirected to another page.
Let's look a little more closely. The first interesting piece of code is the client-side script section, which we've placed near the top of the page. To ensure that the user entered the password that they intended, the system requires that they enter it twice – in the Password and Verify Password fields on the form. So the purpose of the VerifyData() function is to compare these two values:
<SCRIPT language="JavaScript">
<!--
function VerifyData()
{
if (document.frmUser.Password.value != document.frmUser.VerifyPassword.value)
{
alert ("Your passwords do not match - please reenter");
return false;
}
else
return true;
}
-->
</SCRIPT>
We've chosen to use JavaScript for our client-side validation routines, because it's compatible with a greater number of browsers. We've also chosen to perform this check on the client-side, rather than have the server validate the passwords – if the passwords don't match, this saves us a round-trip to the server. In this case, we display a message box which informs the user of the problem and gives them another chance to complete the password fields. If the passwords do match, then the processing continues.
The VerifyData() client-side function is called at the time the form is submitted. We achieve this by adding the onSubmit parameter to the <FORM> tag. The onSubmit parameter identifies a client-side function that is to be called whenever the user submits the form:
<FORM ACTION="AddUser.asp" NAME="frmUser" METHOD="POST"
onSubmit="return VerifyData()">
In this case, when the form is submitted, the VerifyData() executes and returns a result of either true or false (according to whether or not the values of the Password and Verify Password fields matched).
As we mentioned earlier, Register.asp is dual-purpose – as well as collecting registration details for new users, we can use it to allow existing users to modify their details. How do we differentiate between these two cases? We've used a querystring variable called Update. If the value of this variable is True then we know that we're dealing with a user who wants to update existing registration details. Otherwise, we're dealing with a new user. Thus, we can customize the display accordingly:
<%
If Request("Update") = "True" then
Response.Write "<H1>Wrox Classifieds<BR> Update User Registration</H1>"
Else
Response.Write "<H1>Wrox Classifieds<BR> New User Registration</H1>"
End If
%>
If you flick forward a few pages, you'll find that pages such as BrowseListings.asp and MenuForRegisteredUsers.asp contain an Edit Registration Info hyperlink, which provides a click-through to Register.asp?Update="True".
In fact, we've customized the message even further. We've added a special message for any user who tries to log on using Login.asp (see later), but whose login details are not matched with data contained in the database. In this case, we need to ask the unrecognized user to re-register with the system. To do this, we redirect the user to Register.asp?NotFound="True" – and we use the querystring variable called NotFound to tailor the message accordingly:
<%
If Request("Update") = "True" Then
Response.Write "Please change your registration information as listed below<P>"
Else
If Request("NotFound") = "True" Then
Response.Write "<I>We were unable to locate your information. " & _
"Please take the time to register again.</I><P>"
Else
Response.Write "<CENTER>(If you're already registered with us, " & _
"then click the 'Login' link below.)</CENTER><P>"
End If
...
End If
%>
The registration information itself is collected in an HTML form. If we're using the form to update existing information, then it would be good to display the existing information within the form (so the user can see their 'initial values'). In our application, each logged-on user's information is stored in session-level variables. Hence, it is a simple matter of retrieving the information for each of the fields from its corresponding session-level variable:
<FORM ACTION="AddUser.asp" NAME="frmUser" METHOD="POST"
onSubmit="return VerifyData()">
<TABLE BORDER=0>
<TR>
<TD WIDTH=20% ROWSPAN=11> </TD>
<TD>E-Mail Address:</TD>
<TD><INPUT TYPE="Text" NAME="email" VALUE="<%= Session("EMailAddress")%>"
SIZE="40"></TD>
</TR>
<TR>
<TD>Given Name:</TD>
<TD><INPUT TYPE="Text" NAME="GivenName" VALUE="<%= Session("GivenName")%>"
SIZE="40"></TD>
</TR>
...
In the case of a new user, the session-level variables will be 'undefined', and consequently will have no values – so they will just return blank strings.
This works because, if the session variable has not been assigned any other value, then it is assumed to contain an empty string.
There's one exception to this – the Verify Password field. We want to force the user to type in their password at least once, in order to verify their identity. Hence, we don't associate a default value with the VerifyPassword verification field:
...
<TD> <P>Password:</TD>
<TD VALIGN=bottom><INPUT TYPE="Password" NAME="Password"
VALUE="<%= Session("Password") %>" SIZE="40"></TD>
</TR>
<TR>
<TD>Verify Password:</TD>
<TD><INPUT TYPE="Password" NAME="VerifyPassword" SIZE="40"></TD>
</TR>
<TR>
<TD></TD>
<TD ALIGN=CENTER COLSPAN=2><BR>
<INPUT TYPE="Submit" VALUE="Submit Registration">
<INPUT TYPE="RESET"></TD>
</TR>
</TABLE>
</FORM>
When the user clicks on the Submit Registration button, and the form is accepted (that is, their password values match), processing is passed to the AddUser.asp file (as specified in the ACTION attribute of the <FORM> tag above). Let's look at AddUser.asp now.
Handling Registration Details
AddUser.asp is a bit different from most ASP script files, in that it doesn't have a user interface. Its sole purpose is to take the information submitted by the form in the Register.asp page, and to put those values into the database. Based on the results of these database functions, the browser is directed to another page, where the user continues with the application.
Try It Out – Adding Registration Details to the Database with AddUser.asp
1. Create a new file in your editor and enter the following code:
<!--#include file="Clssfd.asp"-->
<%
Dim rsUsers
Set rsUsers = Server.CreateObject("ADODB.Recordset")
rsUsers.Open "Person", objConn, adOpenForwardOnly, adLockOptimistic, adCmdTable
If Session("PersonID") <> "" Then ' currently logged-on user
rsUsers.Filter = "PersonID = '" & Session("PersonID") & "'"
Else ' New session
rsUsers.Filter = "EMailAddress = '" & Request.Form("email") & "'" & _
"AND Password = '" & Request.Form("password") & "'"
If rsUsers.EOF Then ' User not found
rsUsers.AddNew ' ...so add a new record
' Else
' Email address and password matched with DB records -
' In this case we'll allow this to update user's personal details
End If
End If
' write personal details to record
rsUsers("EMailAddress") = Request.Form("email")
rsUsers("Password") = Request.Form("password")
rsUsers("Surname") = Request.Form("Surname")
rsUsers("FirstName") = Request.Form("FirstName")
rsUsers("StreetAddress1") = Request.Form("Address1")
rsUsers("StreetAddress2") = Request.Form("Address2")
rsUsers("City") = Request.Form("City")
rsUsers("State") = Request.Form("State")
rsUsers("PostalCode") = Request.Form("PostalCode")
rsUsers("Country") = Request.Form("Country")
rsUsers("Active") = True
rsUsers("LastLogin") = Now
rsUsers.Update ' update the database
Dim strName, strValue ' create session variables
For each strField in rsUsers.Fields
strName = strField.Name
strValue = strField.value
Session(strName) = strValue
Next
Session("blnValidUser") = True ' declare that current user is validated
Response.Redirect "MenuForRegisteredUsers.asp"
%>
2. Save this file as AddUser.asp.
3. Now we'll create the include file that was called from the file above. Create another file in your editor and enter the following code:
<!-- METADATA TYPE="typelib"
FILE="E:\Program Files\Common Files\System\ado\msado15.dll" -->
<%
Dim objConn
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
"Data Source= E:\datastores\classified_2000.mdb"
If Session("blnValidUser") = True and Session("PersonID") = "" Then
Dim rsPersonIDCheck
Set rsPersonIDCheck = Server.CreateObject("ADODB.Recordset")
Dim strSQL
strSQL = "SELECT PersonID FROM Person " & _
"WHERE EMailAddress = '" & Session("EMailAddress") & "';"
rsPersonIDCheck.Open strSQL, objConn
If rsPersonIDCheck.EOF Then
Session("blnValidUser") = False
Else
Session("PersonID") = rsPersonIDCheck("PersonID")
End If
rsPersonIDCheck.Close
Set rsPersonIDCheck = Nothing
End If
%>
In the 6th and 7th lines of code here for step 3, if you are using the classified_97.mdb substitute
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
"Data Source= E:\datastores\classified_97.mdb"
4. Save this file as Clssfd.asp, in the same folder as the other .asp files.
5. Note that Clssfd.asp uses the ADO type library that we have used previously.You'll need to check that the path of this file is correct for your machine.
6. We'll add just one more ASP page at this stage – so create one more new file and insert the following code:
<%
If Session("PersonID") = "" Then
Response.Redirect "Login.asp"
End If
%>
<BASEFONT FACE="Comic Sans MS" COLOR="DarkBlue">
<HTML>
<HEAD>
<TITLE>Wrox Classifieds</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFF80">
<CENTER><H1>Wrox Classifieds<BR>Registered Users' Menu</H1>
<H3>Welcome <%= Session("GivenName") %></H3>
</CENTER><P>
Thank you for visiting the Wrox Classifieds site. We offer you the opportunity to:
<UL>
<LI>Browse for items on sale
<LI>Bid for items on sale
<LI>Sell your own items on these pages
</UL>
<HR>
<TABLE BORDER=0 WIDTH=100%>
<TR ALIGN=CENTER>
<TD WIDTH=33%><A href="BrowseListings.asp">Browse the listings</A></TD>
<TD WIDTH=33%><A href="ViewMySaleItems.asp">List/Edit Sale Items</A></TD>
<TD WIDTH=33%><A href="Register.asp?Update=True">Edit Registration Info</A></TD>
</TR>
</TABLE>
</BODY>
</HTML>
7. Save this file as MenuForRegisteredUsers.asp, in the same folder as the other .asp files.
8. In Register.asp, type some registration details into the form and click the Submit Registration button. If your details are valid, this will handle your registration and take you to the MenuForRegisteredUsers.asp page:
|
|
How It Works
AddUser.asp leaps into action when the user submits the form on Register.asp. AddUser.asp captures the contents of the form (with in the Request object's Form collection) and places this data into the database. The first line of the AddUser.asp file is a server-side include (SSI) directive:
<!--#include file="Clssfd.asp"-->
This directive instructs the ASP script processor to load the file named Clssfd.asp, and process its contents as if it were part of the AddUser.asp file. In this application, the Clssfd.asp SSI is used to encapsulate all the data access connection information into a single file.
The first line of Clssfd.asp contains a reference to the ADO type library that we encountered in Chapter 12:
<!-- METADATA TYPE="typelib"
FILE="E:\Program Files\Common Files\System\ado\msado15.dll" -->
This file contains definitions of all the constants used as parameters when working with the ADODB objects. By using these predefined constants, instead of their numerical equivalents, our code will be more readable.
The remainder of Clssfd.asp is used to perform two functions. The first declares a variable that will hold the database connection and then creates and opens that connection:
Dim objConn
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
"Data Source= E:\datastores\classified.mdb"
We touched on this little fragment of code earlier in the chapter. We create an instance of the ADO Connection object, called objConn. Then we use it to open a connection to the Classified.mdb database, which we created earlier in the chapter. In order to do this, we use the Microsoft Jet data Provider for Access Databases (as specified in the Provider attribute here).
There are two advantages to placing this code within an SSI like this. First, we can place the SSI directive for Clssfd.asp at the top of any ASP page that needs a connection to our database. Second, if we decide to move our database to another location, we only need to change the Clssfd.asp code – we don't need to change the code in all the other files.
The second function of Clssfd.asp is to retrieve the current user's PersonID value from the Person table. Once the user has successfully registered, this value will be needed throughout the remainder of the user session. The Clssfd.asp file will be included into any ASP script that performs database access, and it just happens to be a convenient place to ensure that we have this value.
Here's how this works. We have a session variable called blnValidUser – if we're working with a logged-in user then the value of this variable is True. (You'll see blnValidUser cropping up elsewhere in the application too.) If we're working with a logged-in user but the PersonID session variable is blank, then we set about repopulating it from the database:
If Session("blnValidUser") = True and Session("PersonID") = "" Then
We do this simply by querying the Person table of the database for the information that we need. The results of the query will be returned as a recordset – so first we need to create the recordset:
Dim rsPersonIDCheck
Set rsPersonIDCheck = Server.CreateObject("ADODB.Recordset")
Dim strSQL
strSQL = "SELECT PersonID FROM Person " & _
"WHERE EMailAddress = '" & Session("EMailAddress") & "';"
rsPersonIDCheck.Open strSQL, objConn
The SQL query here is written so that it retrieves only the PersonID field, rather than the entire record. The WHERE clause tells the SQL query the e-mail address of the user in question. Then the query goes in search of the user's PersonID value.
If there is no information in the database for the given e-mail address, then the current user is logged out by setting the session-level variable blnValidUser to False. Otherwise, the PersonID value is stored in a session-level variable called PersonID. Finally, we can close the rsPersonIDCheck recordset and release its resources:
If rsPersonIDCheck.EOF Then
Session("blnValidUser") = False
Else
Session("PersonID") = rsPersonIDCheck("PersonID")
End If
rsPersonIDCheck.Close
Set rsPersonIDCheck = Nothing
End If
And that's it for Clssfd.asp – so we can return to the execution of AddUser.asp. We've already used objConn.Open to open the database connection, and (if the user is already a valid user) we've ensured that the Session("PersonID") variable is populated. We're now in a position to add the necessary data to the database. To handle the interaction with the Person table, we'll use another recordset object called rsUsers:
Dim rsUsers
Set rsUsers = Server.CreateObject("ADODB.Recordset")
rsUsers.Open "Person", objConn, adOpenForwardOnly, adLockOptimistic, adCmdTable
The rsUsers.Open command will populate the recordset with the contents of the Person table. We've used the adLockOptimistic parameter to this method call, which will allow us to write information into the table.
Recall that adOpenForwardOnly, adLockOptimistic and adCmdTable are all constants, and are defined within the ADO type library (msado15.dll).
Now, if we're working with a new user then we'll need to add a new record to the recordset. On the other hand, if we're working with an existing user it wouldn't make sense to add a new record – instead we'll need to locate the existing record in the recordset. To handle all this, we check to see whether the PersonID session variable is populated, and then we filter the recordset according to the result:
If Session("PersonID") <> "" Then ' currently logged-on user
rsUsers.Filter = "PersonID = '" & Session("PersonID") & "'"
Else ' New session
rsUsers.Filter = "EMailAddress = '" & Request.Form("email") & "'" & _
"AND Password = '" & Request.Form("password") & "'"
If rsUsers.EOF Then ' User not found
rsUsers.AddNew ' ...so add a new record
' Else
' Email address and password matched with DB records -
' In this case we'll allow this to update user's personal details
End If
End If
Remember that the PersonID field is unique to the user. If the Session("PersonID") variable is populated then it will refer to a unique record in the Person table of the recordset – so we can be sure that the user is not overwriting another user's information.
By contrast, if Session("PersonID") is not populated, and the email/password combination doesn't match any record in the Person table, then we know we're dealing with a new user – and we add a new record to the recordset, using AddNew.
Having located the existing record or created a new one, it's time to retrieve the user's registration details from the Request object's Form collection, and copy them into the corresponding fields of the current record of the recordset:
rsUsers("EMailAddress") = Request.Form("email")
rsUsers("Password") = Request.Form("password")
rsUsers("FamilyName") = Request.Form("FamilyName")
rsUsers("GivenName") = Request.Form("GivenName")
...
rsUsers("LastLogin") = Now
If we're updating an existing record, then the new values will simply overwrite any existing data. Otherwise, the data is written to the new user's record. Once all of the information has been added, the data is written to the database by using the Update method of the recordset object.
rsUsers.Update
The next step is to write all of the information from the recordset into session-level variables. There is no single method that will automatically perform this copying process. We could have written a series of statements that copied each field from the recordset to the session-level variable, but that would have been pretty tedious. Instead, we utilize the Fields collection of the Recordset object, which contains all of the individual Field objects in the recordset:
Dim strName, strValue
For Each strField in rsUsers.Fields
strName = strField.Name
strValue = strField.value
Session(strName) = strValue
Next
We use the For Each statement to iterate through each field in the collection. We retrieve the name and value of each Field object; then we can create a corresponding session-level variable that has the same name as the Field object, and assign it the same value.
Now, the user is successfully registered. Ideally, the user shouldn't need to go back and log in straight away – so we immediately grant them "logged-on" status. We set the blnValidUser session-level variable to True, and instruct the client browser to load the MenuForRegisteredUsers.asp page automatically. This will present a registered user's home page to our newly-registered user:
Session("blnValidUser") = True
Response.Redirect "MenuForRegisteredUsers.asp"
Let's take a quick look at MenuForRegisteredUsers.asp. This page provides a different set of navigational tools, and displays a personalized greeting to the user. Later in this chapter, we will add to the registered user's home page to provide additional information.
Since this page is for registered users only, the first thing we do on this page is check the value of Session("PersonID"), to confirm that the user really is properly registered. If they are not, then their browser is redirected to the login page, so that the user may log into the system:
<%
If Session("PersonID") = "" Then
Response.Redirect "Login.asp"
End If
%>
To provide a personalized greeting to the user, we display their name in a welcome message. Since all of the user information is stored as session-level variables, there is no need to perform any database access to retrieve this information. It can simply be retrieved from the appropriate session-level variables:
<CENTER><H1>Wrox Classifieds<BR>Registered Users' Menu</H1>
<H3>Welcome <%= Session("GivenName") %></H1>
</CENTER><P>
Managing User Login
If you were a user who'd registered on a previous occasion, and you were coming to revisit the site, then you wouldn't expect to be asked to go through the registration process again. So, to allow previously-registered users to identify themselves, we will present a login page, Login.asp. We'll also need another page, CheckLogin.asp, which will check the details against the database and redirect the user accordingly. These two pages serve as an alternative route from Default.asp to MenuForRegisteredUsers.asp.
Try It Out – The Login Screen and Login Checker
1. Create a new ASP file and key in the following code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<BASEFONT FACE="Comic Sans MS" COLOR="DarkBlue">
<HTML>
<HEAD>
<TITLE>WROX Classifieds - Login</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFF80">
<CENTER><H1>WROX Classifieds<BR>Login</H1></CENTER>
<P>
<% If Request("Again") = "1" then
if Request("BadPW") = "True" then %>
Invalid Password<BR>
<% Else %>
E-Mail Address not found. Try again<BR>
<% End If %>
<% End If %>
Please enter your e-mail address and password to login to the system.
<FORM ACTION="CheckLogin.asp<% If Request("Again") = "1" then %>?Again=1
<% End If %>" METHOD="POST">
<TABLE BORDER=0>
<TR>
<TD>E-Mail Address:</TD>
<TD><INPUT TYPE="Text" NAME="email"
<% If Request("Again") = "1" then %>
VALUE="<%= Session("EMailAddress") %>"
<% End If %>
SIZE="40"></TD>
</TR>
<TR>
<TD>Password:</TD>
<TD><INPUT TYPE="Password" NAME="Password" SIZE="40"></TD>
</TR>
<TR>
<TD></TD>
<TD align=center><INPUT TYPE="Submit" VALUE="Login">
<INPUT TYPE="RESET"></TD>
</TR>
</TABLE>
</FORM>
<HR>
<TABLE BORDER=0 width=100%>
<TR align=center>
<TD width=33%><A href="browse.asp">Browse the listings</A></TD>
<TD width=33%>Login</TD>
<TD width=33%><A href="register.asp">I'm a new user</A></TD>
</TR>
</TABLE>
</BODY>
</HTML>
2. Save the file as Login.asp, in the same directory as your other ASP files.
3. Create another new ASP file using your editor and enter the following code:
<!--#include file="Clssfd.asp"-->
<%
Dim strEMail, strPassword
strEMail = Request("EMail")
strPassword = Request("Password")
Dim rsUsers
set rsUsers = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Person WHERE EMailAddress = '" & strEMail & "';"
rsUsers.Open strSQL, objConn
If rsUsers.EOF Then ' User not found
Session("EMailAddress") = Request("EMail")
If Request("SecondTry") = "True" then ' User's had two goes
Response.Redirect "register.asp?NotFound=True" ' - must register
Else ' Username wrong; password wrong
Response.Redirect "login.asp?SecondTry=True" ' - allow another go
End If
Else 'One or more users found - check password
While Not rsUsers.EOF
If UCase(rsUsers("Password")) = UCase(strPassword) Then ' password matched
Dim strName, strValue
For Each strField in rsUsers.Fields
strName = strField.Name ' populate session variables
strValue = strField.value
Session(strName) = strValue
Next
Session("blnValidUser") = True
Response.Redirect "MenuForRegisteredUsers.asp" ' successful login
Else
rsUsers.MoveNext
End If
Wend
Session("EMailAddress") = Request("EMail") ' if we get this far then...
' ...password doesn't match any of DB entries
If Request("SecondTry") = "True" then ' User's had two goes
Response.Redirect "register.asp" ' - must reregister
Else ' Username right; password wrong
Response.Redirect "login.asp?SecondTry=True&WrongPW=True"
'- allow another go
End If
End If
%>
4. Save the file as CheckLogin.asp, in the same directory as your other ASP files.
5. Now, you can start a fresh session at Default.asp – click on the Login hyperlink to view the login page, and enter your login information:
|
|
6. Now click on the Login button. This will check your login information against the information contained in the database and then take you to the registered user's home page, MenuForRegisteredUsers.asp.
How It Works
Login.asp allows a previously-registered user to log into the system without going though the entire registration process again. They just type their e-mail address and password into the form, and submit this data. With some web servers, the user registration can be accomplished with the web server itself. In our example, we will be performing the validation within our own ASP code.
Like Register.asp, there is more than one scenario in which Login.asp may be called, and again we can customize the exact appearance of the page to suit the occasion. In the code above, you'll see that CheckLogin.asp handles an unsuccessful login attempt by redirecting the user to Login.asp, specifying the querystring SecondTry=True (and possibly also WrongPW=True). We use these values in Login.asp, to tailor the message that the user sees, based on the results of any previous login attempt:
If Request("SecondTry") = "True" Then ' User's second attempt at logging in
If Request("WrongPW") = "True" Then ' Right email; wrong PW
Response.Write "Invalid Password. Please try again: " & _
"if you get it wrong we'll ask you to re-register.<BR>"
Else ' Wrong email
Response.Write "E-Mail Address not found. Please try again: " & _
"if you get it wrong we'll ask you to re-register.<BR>"
End If
End If
Response.Write "Please enter your e-mail address and password " & _
"to login to the system."
Like Register.asp, we use an HTML form to collect the login information. If the user is re-entering login information, we can help them by displaying e-mail address that they entered on their first attempt:
<TR>
<TD>E-Mail Address:</TD>
<TD><INPUT TYPE="Text" NAME="email"
<% If Request("SecondTry") = "True" then %>
VALUE="<%= Session("EMailAddress") %>"
<% End If %>
SIZE="40"></TD>
</TR>
This helps the user to work out what they might have done wrong on their first attempt.
To submit the login information, the user presses the Login button. Then, the CheckLogin.asp script file performs the task of validating this information against the database.
CheckLogin.asp is like the AddUser.asp script file in that it has no user interface. Since it will perform database access, we include the Clssfd.asp SSI file. Then, to add to the legibility of the text and increase the performance of the script, we copy the user's e-mail address and password values from the Request.Form collection into a couple of locally-defined variables, strEMail and strPassword:
<!--#include file="Clssfd.asp"-->
<%
Dim strEMail, strPassword
strEMail = Request("EMail")
strPassword = Request("Password")
In order to parse the user's login details, we need to query the Person table of the database. We place the results of the query into a recordset, and then compare the values of strEMail and strPassword with the values contained in the recordset. If there's a match, then the user is successfully identified. If not, we need to take alternative action.
So, first let's look at the database query. We create a new ADO Recordset object, define the SQL query and execute the query by opening the recordset against the database like this:
Dim rsUsers
set rsUsers = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Person WHERE EMailAddress = '" & strEMail & "';"
rsUsers.Open strSQL, objConn
Here, the SQL statement queries the Person table for all records whose e-mail address matches the one supplied by the user. The results of this SQL query are stored in the rsUsers recordset.
Now we can start the check. First, did the SQL query return any records at all? If not, then the
e-mail address given by the user doesn't match anything found in the database. In this case, we place the user's e-mail address into a session variable and redirect them to Register.asp (if it's their second attempt to register) or back to Login.asp (if it's their first attempt):
If rsUsers.EOF Then ' User not found
Session("EMailAddress") = Request("EMail")
If Request("SecondTry") = "True" then ' User's had two goes
Response.Redirect "register.asp?NotFound=True" ' - must register
Else ' Username wrong; password wrong
Response.Redirect "login.asp?SecondTry=True" ' - allow another go
End If
...
The alternative is that the SQL query succeeds in populating the recordset with one or more records – which means that we have one or more records whose EmailAddress field matches that given by the user. In this case, we now need to compare passwords. In our application, passwords are not case sensitive. We force both the password from the database and the one submitted by the user to uppercase, before performing the comparison:
Else 'One or more users found - check password
While Not rsUsers.EOF
If UCase(rsUsers("Password")) = UCase(strPassword) Then ' password matched
If the passwords do match, then we have a valid user. In this case, we copy the contents of the current record into a set of session variables, set the blnValidUser flag to True and redirect the client to MenuForRegisteredUsers.asp (in fact, this next fragment is very similar to code that we saw earlier, in AddUser.asp):
Dim strName, strValue
For Each strField in rsUsers.Fields
strName = strField.Name ' populate session variables
strValue = strField.value
Session(strName) = strValue
Next
Session("blnValidUser") = True
Response.Redirect "MenuForRegisteredUsers.asp" ' successful login
If the user's password and the password contained in the record are not the same, then we move to the next record in the recordset, and try the comparison again:
Else
rsUsers.MoveNext
End If
Wend
If we get to the end of the recordset in this way, then we've got a successful email match but we can't match the passwords successfully. In this final case, we will again redirect the user either to Register.asp or to Login.asp:
Session("EMailAddress") = Request("EMail") ' if we get this far then...
' ...password doesn't match any of DB entries
If Request("SecondTry") = "True" then ' User's had two goes
Response.Redirect "register.asp" ' - must reregister
Else ' Username right; password wrong
Response.Redirect "login.asp?SecondTry=True&WrongPW=True" '- allow another go
End If
End If
Finally, note that we've used Response.Redirect here to redirect the user to a different page. As we've mentioned in previous chapters, ASP 3.0 offers two new methods for executing other pages – they are Server.Transfer and Server.Execute. Note that all three methods work quite differently. In this situation in particular, Response.Redirect is preferred to Server.Transfer – although the latter avoids a round-trip to the client, it doesn't support querystrings and it doesn't reflect the current page in the browser's Address window.
We've now got a complete, albeit simplistic, user login and registration system for our application. The next step is to allow registered users to start managing the items that they have for sale.
| << 15.3.1- The Home Page | Chapter15 | 15.3.3- Managing Items for Sale >> |

RSS



