Cincom

Using Session Variables for the Login Page


| Web Toolkit Tutorial Home | Table of Contents | Server-Side Includes | Extending the use of Session Variables |
Now that we have a good working solution using cookies to save employee information, we will now substitute cookies with session variables. This will allow us to do more things with the application.

This lesson will demonstrate how pull data from an HTML form and compare it to data residing in a file. If the login is unsuccessful, we will give the employee the opportunity to login again. If the login is successful, we will redirect the employee to a welcome page and remember who they are when they get there using session variables.

1. If VisualWorks is not already running, please start running it now, load the Web Toolkit parcel and start a Wave HTTP server. You should also file in the code from Toyz Inc 1 and make sure the initialize method of the Filestuff class sets the correct location of the directory variable (i.e. the directory that contains the 3 data files).

2. Although not many people pay attention to the title bar (window caption) of their browser, some of the Toyz Inc. employees have. They noticed that it's the same on every page (The Toyz Inc. TEACH System). They would like to see the title change and reflect what page they are really viewing.

The reason the title bar (window caption) of their browser is the same on every page is because of our include file. The title is "hard-coded" in our header include file. This will have to change and it's quite easy to do.

3. Start with the file header3.inc. Change the hard-coded title and replace it with an expression of a variable. Save this file as header4.inc. The one-line change looks something like this:

<title><%= title %></title>

What will now happen is that on every SSP page, we will define the variable title to the name (or title) of the page. Of course, we will have to do this before we include the header file.

4. Start with the file login3.ssp. Insert a code block at the very beginning of the file to define the variable title. Change the include statement for header4.inc and footer4.inc and change the ACTION attribute for the FORM tag to validate4.ssp. Save file as login4.ssp. The first 5 lines of this file should be the following:

<%
title := 'Toyz Inc. Login Page'.
%>

<!-- #include file= "header4.inc" -->

<form action=validate4.ssp method=post name=form4>

Remember to also change the last line of the file:

<!-- #include file= "footer4.inc" -->

5. Simply copy footer3.inc to footer4.inc. No changes are required at this time but we will modify footer4.inc later in this lesson.

6. Let's make sure our solution works. Fire up login4.ssp. Sure enough, it does!

7. Start with the file validate3.ssp. If a valid user, create a session variable containing an instance of the Employee class. Redirect user to home4.ssp. If not a valid user, redirect user back to login4.ssp. Pass home4.ssp a query string indicating an error. Save the file as validate4.ssp. The file should look like as follows:

<%
firstName := request anyFormValueAt: 'firstName'.
lastName := request anyFormValueAt: 'lastName'.
passWord := request anyFormValueAt: 'passWord'.

errorMessage := '111'.
employees := (Toyz new) getEmployees.
employees do:
 [ :each |
 (passWord = each number) ifTrue:
  [
  (lastName = each lastName) ifTrue:
   [
   (firstName = each firstName) ifTrue:
     [
     session at: 'signon' put: each. ].
     ].
   ].
  ].

session at: 'signon' ifAbsent:
[ response redirectTo: ('login4.ssp?msg=',errorMessage). ].
session at: 'signon' ifPresent:
[ :signon | response redirectTo: 'home4.ssp'. ].
%>

Let's look at this code (what's new) line by line (or chunk by chunk) and make sure you understand what each line (or chunk) does.

session at: 'signon' put: each.
Here is another instrinsic object of the ASP model - session. Since each contains an object of the Employee class, we are storing an instance of the Employee class into a session variable called signon. The syntax is very straight-forward with the at:put: method, something that might be familiar to experienced Smalltalkers.
session at: 'signon' ifAbsent:
[ response redirectTo: ('login4.ssp?msg=',errorMessage). ].
session at: 'signon' ifPresent:
[ :signon | response redirectTo: 'home4.ssp'. ].
Here are 2 very handy methods of the session object. If the employee did not successfully signon, then the line of code that creates the session variable would not have been executed. Therefore, the session variable would not exist and would be "absent". The ifAbsent: method checks for that and expects, as a parameter, a code block. Since this is a failed login attempt, the code block sends the user back to the login page.

If the employee did successfully signon, then the line of code that creates the session variable is executed and the session variable would exist. The ifPresent: method checks for that and expects, as a parameter, a code block with the name of the session variable as an iteration variable, much like that of a collection. In this case, we really don't need to do anything with the value of the session variable - we just wanted to know if it existed. Since it does, we will send the user to the home page.
8. Next up is the home page. Start with the file home3.ssp. Insert a code block to intialize the title of the page before including header4.inc. Now change the "cookie" logic to "session" logic. Also remember to include footer4.inc. The file should look like as follows:

<%
title := 'Toyz Inc. Home Page'.
%>

<!-- #include file= "header4.inc" -->

<table width=90% border=0>
<tr>
<td width=200 align=center>

<%
signon := session at: 'signon' ifPresent:
 [ :signon |
  response write: '<a href=employees4.ssp>List of Employee Courses</a>'.
  response write: '</td>'.
  response write: '<td align=center>'.
  response write: ('<h3>Hello ', signon firstName,'</h3>').
 ].
session at: 'signon' ifAbsent:
 [
  response write: '<a href=login4.ssp>Login Again</a>'.
  response write: '</td>'.
  response write: '<td align=center>'.
  response write: '<h3>Your session has timed out. Please login again.'.
 ].
%>
</td>
</tr>
</table>

<!-- #include file= "footer4.inc" -->

In this case, with the ifPresent: method, we will actually use the value of signon in the same manner as any other object. This was the intent of the code block for the ifPresent: method.

signon := session at: 'signon' ifPresent:
 [ :signon |
  response write: '<a href=employees4.ssp>List of Employee Courses</a>'.
  response write: '</td>'.
  response write: '<td align=center>'.
  response write: ('<h3>Hello ', signon firstName,'</h3>').
 ].
Since the session variable is present, we will pass it as a parameter to the code block. The code block contains very similar code as our previous solution except for the last line of the code block. Note that we are using a very familiar Smalltalk syntax of signon firstName to display the (first) name of the employee. Since signon now contains an instance of the Employee class, we can use any method that exists with the Employee class. This would include getter methods like lastName, employeeNumber and level.

The logic for the session being absent is very similar to that of our validate routine. We need to put this here because session variables have a default lifespan of 20 minutes. It's very possible that the employee got to this page, went to lunch, came back and clicked the refresh button on the browser. If this is the case, and the employee took a lunch longer than 20 minutes, then the session variable would not exist. This code block catches that.
9. Last but not least is the list of employees. At this stage, there is not much to change except for the title and the include files. The file should look something like this:

<%
title := 'List of Employees at Toyz Inc.'.
%>

<!-- #include file= "header4.inc" -->

<table width=90% border=0>
<tr>
<td width=200 align=center>
<a href=home4.ssp>Home Page</a>
</td>
<td align=center>
<table border=1>
<h2>Employees at Toyz Inc.</h2>
<%
toyz := Toyz new.
employees := toyz getEmployees.
employees do: [ :each |
 response write: '<tr>'.
 response write: ('<td>',each number,'</td>').
 response write: ('<td>',each level,'</td>').
 response write: ('<td>',each firstName,' ',each lastName,'</td>').
 response write: '</tr>'.
].
%>
</table>
</td>
</tr>
</table>

<!-- #include file= "footer4.inc" -->

At this point, feel free to test your login process and all pages in the application. For example, let the session variable time out and refresh the home page.
Congratulations! Phase 4 of the login process is complete

Aside from making the title of each page dynamic and substituting "cookie" logic with "session" logic, we did not do that much. However, we have laid the groundwork for a lot more functionality in our application, which we'll get to next.

You now should be able to:
Create session variables
Test for the presence/absense of session variables
Use session variables like objects

| Web Toolkit Tutorial Home | Table of Contents | Server-Side Includes | Extending the use of Session Variables |