\n"); } else { header("Content-type: text/html; charset=utf-8"); } ?> CS-090.3 Assignment 3

Introduction

Build an application that users log into. For this assignment, there are just two web pages: the first is a login screen where the user enters his or her username (email address) and password. The second is a result screen that tells the user whether the login was successful or not, and greets the user by name if the login was successful. The application uses a database to hold usernames, passwords, and real names.−−

Description

  1. Set up your database.

    Use pgAdmin (or any other mechanism you might prefer) to set up the user table in your database so it looks something like this:

    databse screenshot

    Be sure the user column contains only valid email addresses; they do not have to be QC email addresses. The password and name columns may contain arbitrary text, but plausible passwords and people’s names will make the assignment much more fun. When you set up the columns, make sure the “Not null” option is checked for each one. That way you won’t have to worry about rows having empty values for those fields.

  2. Set up the login page.

    Remove the “needJS” and lorem ipsum paragraphs from your site’s index page, and put in a form that uses the POST method attribute and process_form.php as the value of the action attribute. Provide text input elements with corresponding label elements for User and Password entries. And add a Submit button (input element of type submit). Use CSS to make your login page look “nice.”

    Use JavaScript to validate the form data as demonstrated in class. With JavaScript disabled, the user can type anything (or nothing) into the form fields and submit it. But if JavaScript is enabled, the Submit button should be disabled except when the user has entered a valid email address in the User field and any non-empty string in the Password field. Use a regular expression to verify that the email address is valid. Highlight fields that do not contain correct values. For example, the form might look like this if the user enters an invalid email address:

    login screenshot

  3. Implement the action page.

    To keep things simple, the process_form.php file does not need to generate a valid XHTML document. (That’s why the file name ends in .php instead of .xhtml.) All it has to do is to echo one of four messages:

    1. You bad person, you!
    2. Invalid email address.
    3. User not in database.
    4. Welcome, <user’s name from database>!

    You will need to do this part of the project incrementally. Start by echoing the user and password values that you receive from the $_POST superglobal array to make sure they are coming in correctly. To avoid PHP errors, you need to test to see if the elements of the $_POST array that you are interested in are set before you try to access them. See the first few lines of this course’s template.xhtml file for an example of how to do this (for the $_SERVER superglobal). If either of the form variables is not set in the $_POST array, die with the “bad person” message. The die() function echoes a message and stops PHP processing:

    die("<h1>You bad person, you!</h1>");

    The “bad person” might be a hacker trying to activate your form processor without actually going through the login page, or it might be you because you set the form up incorrectly. In either case, you can test this test by pretending to be a hacker: just use a URL like http://localhost/process_form.php to run the script without using the form.

    Once you know the form data is being submitted correctly, use require_once() to load the strip_quotes.php file shown in class to make sure there are no backslashes in front of any quotes the user has typed in either form field. This file is not installed in the lab, so you will need to download it and put it in the same directory as the process_form.php file that references it. There is a Catch-22: if you try to download a .php file from a web server, it will get executed instead of downloaded. So I put it inside a .zip file named strip_quotes.zip that you can download and extract into the proper directory. If you want to put strip_quotes.php in your scripts directory, just use a relative pathname as the argument to require_once().

    Once your form processor has established that there are no backslashes, it must cleanse the values typed by the user by running htmlspecialchars() to block SQL injection attacks, as discussed in class.

    I mentioned to some people after class that you would need to verify that the user field is a valid email address using the PHP regular expression function preg_match(). That was wrong: the user value typed by the user is simply going to be compared to whatever is in the database for this assignment. As long as the database contains only valid email addresses, it doesn’t matter whether the user types a valid email address or not; you can use whatever was in the user field of the form (once it has been inoculated against SQL injection attacks) in the WHERE clause of your query:

    $user = htmlentities($_POST['user'], ENT_QUOTES); $query ="SELECT password, name FROM users WHERE \"user\" = '{$user}'";

    Notes on the SQL query string: The capitalized key words do not need to be capitalized, but it is a convention that makes the string easier to read. The password, name, and user words are column names; user had to be put in double quotes because it conflicts with a builtin keyword that is automatically turned into the database user’s login name. The other column names could optionally be put inside double quotes also. Single quotes (as in '{$user}') are used to specify string values.

    Once you do the database query, you can use the pg_num_rows() function to find out how many rows in the table match the user id (email address) entered on the form:

    $result = pg_query($conn, $query); $num_rows = pg_num_rows($result);

    There are actually three possible query outcomes, indicated by $num_rows, you need to deal with:

    1. zero: The user id is not in the table.
    2. one: The user id is unique in the table.
    3. anything else: The user id occurs multiple times in the table.

    The last case should not occur, and you could add a 'unique' constraint to the user column of the table so the database will prevent it from happening. But even with that constraint, it is good programming practice to “cover all bases.”

    As described above, you can simply use calls to die() to handle the different cases for this assignment.

Submit the Assignment

When you have built and tested your web page, send me an email message to me saying your assignment is ready; I will get a copy from your account on the server and check it out. Send your email to:

Christopher.VickeryATqc.cuny.edu

Be sure the Subject Line of your email says CS-90.3 Assignment 3, just like that, to be sure your message does not get trapped by my spam filters.

Be sure to sign your email so I can tell who sent it!