Due April 26 before midnight
Implement a basic user login, logout, online store, and shopping cart in PHP using sessions and previously-learned PHP/MySQL concepts.
For this project, you will be creating a web-based store in PHP.
It will utilize the concept of session cookies to manage user sessions.
Unlike GET and POST, sessions are useful to store data that is
persistent across multiple web pages for each unique client. This means
that while a client's session is active, every page will have access
to that client's session variables.
This is what makes shopping carts possible in web-based stores. When
you add an item to your cart, it is stored on the server and can only
be retrieved by the user that created the session. PHP stores session
variables in the global array $_SESSION.
In general, session cookies are used to keep track of users who visit or log in to websites (See link about for intro to session cookies). Session cookies pose a potential security risk because if an attacker steals your session cookie, he can use it to log into on to the account that the session cookie is associated with. A common way to steal session cookies is with a XSS (Cross-Site Scripting) attack, which is one of the most commonly exploited website vulnerabilities. XSS attacks often use JavaScript to send a victim's session cookie to the attacker's remote server, where it can be processed by a PHP script and logged to a file.
The best way to prevent XSS attacks from accessing session cookies (or other cookies containing sensitive data) is setting the HTTP-Only flag on cookies. HTTP-Only cookies cannot be accessed by client-side languages (JavaScript).
PHP session cookies can be set to HTTP-Only a few different ways. It can be done in http server configuration files or directly in your PHP scripts. We will be doing it in the PHP script.
When programming websites that use cookies, it is helpful to be able to see the cookies that you have created. In Firefox, right click on a page, then click View Page Source, click details, and finally click view cookies. In Chrome, right click on a page, click inspect element, click Resources, and then click Cookies. There are also more capable cookie management plugins available on the web for most major browsers.
You are going to need to redirect users to pages based on whether they are logged in or not. Redirects can be done by JavaScript or a server-side language like PHP. Use PHP for this assignment. PHP redirects are done by changing the "Location" HTTP header. This is done with the header() function.
header("Location: http://www.example.com/"); exit(); // or header("Location: ./home.php"); exit();
POST and GET methods can be used for sending data from a web browser to a server. We used POST in previous assignments that used forms. POST is useful for forms because the form data won't be sent in the URL and there is no limit to how much data you can send. While this is useful for forms, it is not useful when we want to be able to link to a URL with variable data. This is where GET comes in.
GET encodes variables names and values in the URL. For instance, you
have probably seen a URL like the one below. The question mark ('?')
is a delimiter between the address and the GET variables. Each GET variable
is in the form of variable=value, separated by ampersands ('&').
http://forums.example.com/?forum=news&threadid=1234
In this assignment you will encode links to store items in a similar
fashion. Example PHP code:
echo "<a href='store.php?item=$itemID'>$items['itemName']</a>";
You will also need to access GET variables and use them in your scripts.
Example PHP code:
$itemID = htmlspecialchars($_GET['item']);
SQL Injections refer to an injection attack wherein an attacker can execute malicious SQL statments that control a web application's database server. Sever side scripting languages are not able to determine whether or not the SQL query string is malformed; all they can do is send a string to the database server and wait for the interpreted response. Either use prepared statments to prevent SQL injections or real escape string all variable parameters used within the SQL query string.
This page will contain a generic home page that will display
either a 'guest' page or a 'logged-in' page. This will also
include your navigation from nav.php (described below).
If a user has not logged in, display a page that contains a
generic "Welcome GUEST" prompt and that the user must be logged in to
preview the store. Also navigation to the 'login' page and a link to your
final project proposal page.
Otherwise, display a page that contains a generic
"Welcome $_SESSION['user_fname']" prompt and navigation to the 'store',
to the user's 'shopping cart', to 'logout', and
to your final project proposal page.
If a user is not 'active' display a link to your home page, a link to the login page, and a link to your final proposal page. Otherwise, if a user is 'active' display a link to the home page, the store page, the shopping cart, to logout, and to your final project proposal page. This script will be included for each page.
This page will contain your navigation and a HTML form for user login data. If a user is currently 'active', redirect the user to the home page. Otherwise, display a form and have a text input for the user's username or email, a password input for the user's password, and a submit button. You will validate and authenticate a login request by extracting posted form data (user + password). Validate that there are no missing form fields. Query your 'Users' Table to select all fields where username or email equals the posted username or email. If there was no result set, error, username or email does not exists. Otherwise, authenticate the stored database password and posted password. If the passwords match, set a $_SESSION variable that indicates that a user has successfully logged in and is 'active'. Also store the user's username into the $_SESSION array, then redirect the user to the 'home' page. If a login error occurred, redirect the user to the 'login' page and display an error "invalid username, email, or password".
If the user is NOT 'active', redirect the user to 'home.php'.
If a user is 'active', this will display all of your products
within your 'Products' table.
This page will closely resemble your lab10 for displaying products stored
in your database. You may optionally include a 'sort by' filter, but not
required for this project.
Within the page, display each product from your 'Products' table.
For each product item, include a button called "View Item"
that will link to this page with a query string with the product's id.
For example, if a user clicks on "View Item" for the first product,
the link for the anchor tag would be:
<a href='./store.php?q=1'>View Item</a>
.
Process and output to the page as follows:
If $_GET['q'] is NOT set, query all of your products and display
them to the page similar to lab10.
If $_GET['q'] is set and greater than 0, query your Products table to select
the product where the product's id is equal to $_GET['q'].
If the query value is less than 1 or the queried result set is empty, then
display all the products (default). Otherwise, display only the queried
product and a form with a hidden input with the value of the
product's id with name set to 'store_prod_id' and submit button with value
"Add To Cart". The form's method
will be post and the action will call 'cart.php'. This will only pass
the product's id within the POST parameters to 'cart.php'.
If the user is NOT 'active', redirect the user to 'home.php'.
If the user is 'active', this page will display the current items
within the cart from $_SESSION['cart'].
An item to be added to the
cart will be from a POST request passing a product's id to this script.
If $_POST['store_prod_id'] is set,
query your 'Products' table and SELECT the product's id where the
product id is equal to the passed POST parameter.
If the query was successful, store the product's id into a var called
$added_product_id.
Next, if $_SESSION['cart'] is not set, declare $_SESSION['cart'] = [];
Then,
$_SESSION['cart'][$added_product_id] = isset($_SESSION['cart'][$added_product_id]) ? $_SESSION['cart'][$added_product_id]+1 : 1;
endif $_POST['store_prod_id'] was set.
At this moment, $_SESSION['cart'] is either empty or contains an
associative array where each key is a product's id within the cart
and the value stored at that key is the cart quantity for that product.
To display each item in the user's cart, you will output each item
within a form, this form will either remove an item or update the
cart quantity. Use the following pseudocode as a guide:
//display cart and subtotals if $_SESSION['cart'] is not empty $cart_total=0.0; echo html form action cart.php method POST for each in $_SESSION['cart'] as $prod_id =>$cartQnty query database's Products table and select name, sku, and price where prod_id is equal to $prod_id. if the query was successful, fetch the row by association. Display the name and sku first. Then display an html input type=number where name is equal to $prod_id, min=0, and value=$cartQnty Finally calculate the queried price * $cartQnty and display the sub price for the item(s) in $monetary.00 format. Update the running cart_total with sub price else the query was unsuccessful, optionally, could unset $_SESSION['cart'][$prod_id] or continue (skip) end_foreach echo the $cart_total in monetary format echo a submit button name = 'action' value = 'Empty Cart' echo a submit button name = 'action' value = 'Update Cart' endif //end display cart and subtotals
foreach ($_POST as $key_prod_id=>$qnty) { $qnty = htmlspecialchars($qnty); if(array_key_exists($key_prod_id, $_SESSION['cart'])) { $_SESSION['cart'][$key_prod_id] = $qnty; } }//endforeach ... //display cart and subtotals
If user is 'active', unset the $_SESSION variable and destroy the session. Display to the screen that the user is now logged out and navigation to 'home' or 'login'.
This table may be reused from lab 10. Have at least 6 entries within this table. Refer to lab 10 for the table fields.
Create the following table and manually enter two users via mysql>
This table will contain a user_id, user_uname, user_email, user_password,
user_fname (user_id unsigned int primary key not null auto_increment,
and the rest varchars(255) ).
Within MySQL, manually insert a record to this table with the following values:
test, test@test.com, testpassword, testfname. I will use these
credentials to test and grade your project 2. You are welcome to add more
users, but you are required to enter at least one more user into your table.
Your connect.php will instantiate your $db resource variable and connect your scripts to your database. You must include some styling such that the layout of all your pages are used by the same css file. Within your project2 directory, you must include an images subdir that will contain all of your product images files. Within a text file named tables.txt, perform a mysql describe Users; SELECT * FROM Users; describe Products; SELECT * FROM Products; and copy and paste the output to tables.txt. You may include any extra php, js, css, html, etc within your project, but must be within your project2 directory.
Requirements | Points |
---|---|
home.php | 4pts |
nav.php | 3pts |
login.php | 7pts |
store.php | 10pts |
cart.php | 15pts |
logout.php | 3pts |
Users + Products MySQL Table | 5pts |
connect.php, css, js, images, tables.txt, extras | 3pts |
Total | 50pts |