The ACCOUNT. The ACCOUNT project is an intermediate full-stack project that builds on the previous project, The SITE. We will add user accounts and build some new features that can only be accessed through a log-in. A log-in form will be provided to users, who are then verified against a users table.
You can download scripts for completed versions of the SITE project here if you need them.
You can open a completed version of this project in your browser here.
If you want to download completed versions of the PHP scripts and image files for this project, you can find them here.
This project has a few steps:
Once The ACCOUNT Project is built, the skills and concepts learned will be used to build a password encrypted version to improve site security in the next JAM .
Project Set-up. As before, set up a directory in the htdocs folder to hold your project. I recommend naming it n413_account. We will use the SITE project as the basis for building this one, so copy all the files from the SITE project into your new project folder. You can find them here if you need them.
Be sure your MAMP/XAMPP server is running and check your connection script (n413connect.php) to be sure it uses the correct database connection credentials if you copied in a new version. Check to be sure you have copies of the Bootstrap and jQuery Javascript files, and the Bootstrap CSS file.
Messages Page. Create a special page for "Messages" that were submitted by the "Contact Form". Begin by adding a link to "Messages" in the nav-bar. Open head.php and find the <ul> tag that holds the Nav-bar links. Add a second <ul> tag that will float to the right side of the nav-bar, as shown here:
(head.php) ... <ul class="navbar-nav"> <li id="home_item" class="nav-item"> <a id="home_link" class="nav-link" href="index.php">Home</a> </li> <li id="list_item" class="nav-item"> <a id="list_link" class="nav-link" href="list.php">The List</a> </li> <li id="contact_item" class="nav-item"> <a id="contact_link" class="nav-link" href="form.php">Contact</a> </li> </ul> <ul id="right_navbar" class="navbar-nav ml-auto mr-5"> <li id="messages_item" class="nav-item"> <a id="messages_link" class="nav-link" href="messages.php">Messages</a> </li> </ul> ...
Note: The Bootstrap nav-bar is using display:flex and the flex-box classes for layout, so the usual methods for floating the <ul> tag over to the right will not work. The solution is to use the ml-auto class, ("ml" is "margin-left") which adds as much left-margin as possible.
In addition to the ml-auto class, the mr-5 class is used to give the "Messages" link some right margin.
Check your project in a browser to see the updated nav-bar.
Create a new file in your project named messages.php, and put in the "includes" for the connection script and the <head>:
(messages.php) <?php include("n413connect.php"); include("head.php"); ?>
Next, make a database query that retrieves all the entries from the form_responses table and store the result in an array named $messages:
(messages.php) <?php include("n413connect.php"); include("head.php"); $messages = array(); $sql = "SELECT * FROM `form_responses` ORDER BY timestamp DESC";"; $result = mysqli_query($link, $sql); while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)){ $messages[] = $row; } ?>
This query will get all of the form_response records, ordered by timestamp, with most recent records first. The DESC term in the last line of the query will put the results in "Descending" order.
Add the container-row-column structure for Bootstrap and make a headline for the page. We can test whether there were any messages by checking the number of items in $messages: PHP uses a function called count() to get the size of an array. Let's have it give us feedback if there are no messages:
(messages.php) <?php include("n413connect.php"); include("head.php"); $messages = array(); $sql = "SELECT * FROM `form_responses` ORDER BY timestamp DESC"; $result = mysqli_query($link, $sql); while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)){ $messages[] = $row; } ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <?php if(count($messages) > 0){ echo '<h1>Contact Form Messages</h1>'; }else{ echo '<h2>There are no messages at this time.</h2>'; } ?> </div> <!-- /.col-12 --> </div> <!-- /.row --> </div> <!-- /.container-fluid -->
Test this now by deleting any records in the form_response table. You should see the "No Messages" headline.
Submit a few records with the contact form and test again. You should see the "Contact Form Messages" headline now.
After the headline row, continue with the PHP script that draws a row for each message. Put in a 2-column spacer, a 2-column div for the messgage details (name, email, and timestamp), and a 6-column div for the comment. Format the email with an <a> tag and a "mailto:" address, then display the email address as the link:
(messages.php) ... <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <?php if(count($messages) > 0){ echo '<h1>Contact Form Messages</h1>'; }else{ echo '<h2>There are no messages at this time.</h2>'; } ?> </div> <!-- /.col-12 --> </div> <!-- /.row --> <?php foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6">'.$message["comment"].'</div> </div> <!-- /.row -->'; }?> </div> <!-- /.container-fluid -->
Add some styles to improve the readability of the message list. Have a look at Bootstrap's background color classes. The "bg-light" class will separate the message area from the page without causing too much of an optical effect. A subtle rounded border helps, too. Here are Bootstrap's border and border-radius classes. Padding at level-2 ("p-2") completes the look:
(messages.php) ... <?php foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6 p-2 bg-light border rounded">'.$message["comment"].'</div> </div> <!-- /.row -->'; }?> </div> <!-- /.container-fluid -->
Here's what you get:
Last, drop in the jQuery script to set the page title and the nav-bar classes:
(messages.php) ... </div> <!-- /.container-fluid --> </body> <script> var this_page = "messages"; var page_title = 'AMP JAM Site | Messages'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
Here is the messages.php script so far:
(messages.php) <?php include("n413connect.php"); include("head.php"); $messages = array(); $sql = "SELECT * FROM `form_responses` ORDER BY timestamp DESC"; $result = mysqli_query($link, $sql); while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)){ $messages[] = $row; } ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <?php if(count($messages) > 0){ echo '<h1>Contact Form Messages</h1>'; }else{ echo '<h2>There are no messages at this time.</h2>'; } ?> </div> <!-- /.col-12 --> </div> <!-- /.row --> <?php foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6 p-2 bg-light border rounded">'.$message["comment"].'</div> </div> <!-- /.row -->'; }?> </div> <!-- /.container-fluid --> </body> <script> var this_page = "messages"; var page_title = 'AMP JAM Site | Messages'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
You can view this in a browser here.
The Users Table. The "users" table will hold the data for user accounts. Create a new table in the ampjam_db database and name it "users". Refer back to "The TABLE" if you need to. The new table needs 5 columns :
Add the 5th column just as you did when you created the form_responses table.
Note: The password column is set to TEXT in anticipation of encrypting the password later. Encrypted password strings can be quite long, and it may not be possible to know the length of the string. This table holds unencrypted passwords, which is something you should never do for a working web application. This version is designed as an educational project only, and keeps things simple. The next exercise will take you through the process of encrypting the passwords an adding security practices into your project.
Save the table and have a look at the "Structure" tab. Make any necessary edits or corrections.
Since we will not build a Registration form with this project, click the Insert tab to add a few records. Make a few accounts for testing. The role column will identify accounts with "admin" privileges, so make at least one account with the role set to "1".
You can download the SQL script for the users table here.
PHP Sessions. The Message Page is good, but do you really want just anyone to see your messages? Only people who have permission should be able to see this page. So we need to check to see who is looking at the page. We only want people who are in the users table (with the right role) to see the page. We can use a login form and an SQL query to check whether a user's record is in the users table, and what their role setting is. Then the id and role can be supplied to the page when it loads.
But we don't want to go through this process every time a new page is loaded. We need a "persistent" way to know whether a user is authorized. We can do this with a PHP "session". The PHP session is a small file stored on the Apache server that keeps variables for each person who visits the site. The key to the file is stored in the browser "cookie". When a session is first created, the file is created on the server, and the session id is stored in the browser cookie. All this happens automatically when the PHP function session_start() is used. If no previous session exists, a new session is created. If a session exists, it is opened.
You access the session with a special variable called a "superglobal". It looks like this: $_SESSION. The session variable is an associative array, and is similar to the $_POST and $_GET superglobals we have been using already. These variables are available to any function, regardless of the "scope" of the function, hence the term "superglobals". The data stays in the session until the session is destroyed, so sessions never time out. (However, you can create your own session time-out by checking how long the session has been open and destroying it if too much time has gone by.)
Log-in Form The first step is to add a link for "Log-In" in the nav-bar. Open head.php and add a second <li> tag after the "Messages" link for the log-in form, as shown here:
(head.php) ... <ul class="navbar-nav"> <li id="home_item" class="nav-item"> <a id="home_link" class="nav-link" href="index.php">Home</a> </li> <li id="list_item" class="nav-item"> <a id="list_link" class="nav-link" href="list.php">The List</a> </li> <li id="contact_item" class="nav-item"> <a id="contact_link" class="nav-link" href="form.php">Contact</a> </li> </ul> <ul id="right_navbar" class="navbar-nav ml-auto mr-5"> <li id="messages_item" class="nav-item"> <a id="messages_link" class="nav-link" href="messages.php">Messages</a> </li> <li id="login_item" class="nav-item"> <a id="login_link" class="nav-link" href="login.php">Log-In</a> </li> </ul> ...
Now, create the login.php file in your project folder and add the "include" for head.php. There's no need for a connection script here, as the data will be POSTed to the script that connects to the database. The script for the log-in form will be very similar to the Contact form, with a few differences. Open the Bootstrap container-row-column structure, add a headline, then write the form:
(login.php) <?php include("head.php"); ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-in</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <form method="POST" action="n413auth.php"> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div id="form-container" class="col-4"> User Name: <input type="text" id="username" name="username" class="form-control" value="" placeholder="Enter User Name" required/><br/> Password: <input type="password" id="password" name="password" class="form-control" value="" placeholder="Enter Password" required/><br/> <button type="submit" id="submit" class="btn btn-primary float-right">Submit</button> </div> <!-- /#form-container --> </div> <!-- /.row --> </form> </body> <script> var this_page = "login"; var page_title = 'AMP JAM Site | Login'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
The "action" attribute for the form should be n413auth.php, a file we will create in a later step. The input attributes should be "username" and "password", and the "password" input should be of type "password".
The Javascript variable for the page name should be "login", and set the page title to your liking.
n413auth.php Create the file for authorizing the log-in. Name the file "n413auth.php" and place it in your project folder. This script will have similarities to n413post.php. You can copy the "includes" and sanitize() function from n413post.php, then modify the variables that are initialized and loaded from the $_POST array:
(n413auth.php) <?php include("n413connect.php"); function sanitize($item){ global $link; $item = html_entity_decode($item); $item = trim($item); $item = stripslashes($item); $item = strip_tags($item); $item = mysqli_real_escape_string( $link, $item ); return $item; } $username = ""; $password = ""; if(isset($_POST["username"])) { $username = sanitize($_POST["username"]); } if(isset($_POST["password"])) { $password = sanitize($_POST["password"]); } ?>
We will use a "SELECT" query to find whether the username and password submitted by the user exists in the users table:
(n413auth.php) ... $username = ""; $password = ""; if(isset($_POST["username"])) { $username = sanitize($_POST["username"]); } if(isset($_POST["password"])) { $password = sanitize($_POST["password"]); } $sql= "SELECT * FROM `users` WHERE username = '".$username."' AND password = '".$password."' LIMIT 1"; $result = mysqli_query($link, $sql); $row = mysqli_fetch_array($result, MYSQLI_BOTH); ?>
We know mysqli_fetch_array() will return false if there is no record in $result, so we can use Boolean logic with $row to create the login (or not):
(n413auth.php) ... $sql= "SELECT * FROM `users` WHERE username = '".$username."' AND password = '".$password."' LIMIT 1"; $result = mysqli_query($link, $sql); $row = mysqli_fetch_array($result, MYSQLI_BOTH); if($row){ session_start(); $_SESSION["user_id"] = $row["id"]; $_SESSION["role"] = $row["role"]; } include("head.php"); ?>
...and there you have it!
If $_SESSION["user_id"] exists, there is a log in. Also, if $_SESSION["role"] is any number higher than zero, we have admin privileges.
One small wrinkle here is that the "include" for head.php needs to be placed after the session is intiated (or not). There is logic in the nav-bar (or there will be) that checks for whether a log-in or admin privileges exists. Just shift the "include" statement to follow the log-in logic, as shown above.
Now it's time to let the user know whether the log-in was successful. Use the Bootstrap container-row-column structure to lay out the log-in message, as shown. Also add the jQuery script at the end of the script, as you see below:
(n413auth.php) ... <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-in</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div class="col-4 text-center"> <?php if(isset($_SESSION["user_id"])){ echo '<h3>You are now Logged In.</h3>'; }else{ echo '<h3>The Log-In was not successful.</h3> <a href="login.php"><button class="btn btn-primary mt-5">Try Again</button></a>'; } ?> </div> <!-- /.col-4 --> </div> <!-- /.row --> </div> <!-- /.container-fluid --> </body> <script> var this_page = "login"; var page_title = 'AMP JAM Site | Login'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
Test this using the credentials from one of your accounts in the users table.
Once you successfully log in, you will need a way to log out. Let's go ahead and set that up. We can add some PHP to the nav-bar to change the "Log In" link to a "Log Out" link, depending on whether a log-in exists. Open head.php to edit the nav-bar links.
Open PHP tags around the <li> tags that contain the log-in link. The first PHP statement should be session_start(). This makes the $_SESSION variable available. Now check to see if the $_SESSION["user_id"] value exists by using isset(). If $_SESSION["user_id"] exists, echo an <li> tag with a "Log Out" link. Otherwise, echo the Log-In link:
(head.php) ... <ul id="right_navbar" class="navbar-nav ml-auto mr-5"> <li id="messages_item" class="nav-item"> <a id="messages_link" class="nav-link" href="messages.php">Messages</a> </li> <?php session_start(); if(isset($_SESSION["user_id"])){ echo ' <li id="logout_item" class="nav-item"> <a id="logout_link" class="nav-link" href="logout.php">Log-Out</a> </li>'; }else{ echo ' <li id="login_item" class="nav-item"> <a id="login_link" class="nav-link" href="login.php">Log-In</a> </li>'; } ?> </ul> ...
Note: Use care with the "if(isset())" statement. The "if" uses parentheses, and so does isset(). It is easy to accidentally omit the second closing parenthesis.
Of course, you need logout.php to get the log-out link to work:
(logout.php) <?php session_start(); unset($_SESSION); session_destroy(); include("head.php"); ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-out</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div class="col-4 text-center"> <h3>You are now Logged Out.</h3> <a href="login.php"><button class="btn btn-primary mt-5">Log In</button></a> </div> <!-- /.col-4 --> </div> <!-- /.row --> </div> <!-- /.container-fluid --> </body> <script> var this_page = "logout"; var page_title = 'AMP JAM Site | Logout'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
Be sure to "include" head.php after the session code lines, so the nav-bar updates the way you expect it to.
Logging out requires that you unset (delete) the $_SESSION variable. Then you destroy the session. Notice that you need to start a session to destroy it. That's because we only know which session we are dealing with if we start it.
Now that we have a way to log in and log out, let's go back where we started and look at the "Messages" page again. The orginal issue was that we did not want to have just anyone looking at the messages. So there are some things we still need to do if the user should not see the messages:
Tackle the nav-bar first. The PHP script that was just added to the <li> tags in the nav-bar link list has the basic logic needed to hide the "Messages" link. If we have a log-in, we check to see if the role is right. Move the <li> tags that contain the "Messages" link inside the "if" statement, and wrap them in a second "if" statement that checks whether the role is greater than "0":
(head.php) ... <ul id="right_navbar" class="navbar-nav ml-auto mr-5"> <?php session_start(); if(isset($_SESSION["user_id"])){ if($_SESSION["role"] > 0){ echo ' <li id="messages_item" class="nav-item"> <a id="messages_link" class="nav-link" href="messages.php">Messages</a> </li>'; } echo ' <li id="logout_item" class="nav-item"> <a id="logout_link" class="nav-link" href="logout.php">Log-Out</a> </li>'; }else{ echo ' <li id="login_item" class="nav-item"> <a id="login_link" class="nav-link" href="login.php">Log-In</a> </li>'; } ?> </ul> ...
Test this in your browser. Check your users table for credentials that have a "role" of "1", and log in with those. You should see the "Messages" link in the nav-bar. Log out, and it should disappear. Log in again with credentials that have a role of "0", and the "Messages" link should still be hidden.
But it is still possible for someone to use the URL directly and see the messages. You can try this yourself by pointing your browser to the projects folder and adding "/messages.php". You will see the list of messages and a navbar with the "Messages" link hidden.
There are two ways we can prevent this. We could test for the role in the $(document).ready() function, redirecting the page if the test fails. Or we could test in PHP when the messages are drawn to the page. We will use the second method.
Find the "foreach" statement in messages.php and enclose the entire code block in an "if" statement, as shown:
(messages.php) ... <?php if($_SESSION["role"] > 0){ foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6">'.$message["comment"].'</div> </div> <!-- /.row -->'; } //foreach } //if ?> ...
Try this using the direct URL method, and you will see that the messages are not displayed. However, it would good to display a message for the unauthorized user. Add an "else" clause and mark up the layout for an "unauthorized" message:
(messages.php) ... <?php if($_SESSION["role"] > 0){ foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6">'.$message["comment"].'</div> </div> <!-- /.row -->'; } //foreach }else{ echo' <div class="row mt-3"> <div class="col-12 text-center"><h3>You are not authorized to view the messages.</h3></div> </div> <!-- /.row -->'; } //else if ?> ...
Now the messages are only available for authorized users.
The ACCOUNT Project is now complete. You can add features if you like, such as a welcome message that displays the username, etc. Remember, this is a simplified version of an account system, and has serious security weaknesses in the log-in system. Continue on to the next exercise to learn how to encrypt passwords and provide features such as user registration, AJAX-based error mesages, and more.
You can open a completed version of the project in your browser here. Log in as "groot" and see the messages. Guess the password. (No spaces, lowercase.) If you're sratching your head, just Google what Groot says. Groot has permission to see the messages.
You can also log in as "rocket", using password "whatever". Rocket can log in, but does not have privileges to see the messages.
Here are completed versions of the scripts used for this project:
(n413connect.php)<?php $dbhost = 'localhost:8889'; //XAMPP is 'localhost:3306' $dbuser = 'root'; $dbpwd = 'root'; //XAMPP password is '' $dbname = 'ampjam_db'; $link = mysqli_connect($dbhost, $dbuser, $dbpwd, $dbname); if (!$link) { die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error()); } ?>
(head.php)<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes"> <title>Full Stack Amp Jam Site Project</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-3.4.1.min.js" type="application/javascript"></script> <script src="js/bootstrap.min.js" type="application/javascript"></script> <script src="js/bootstrap.min.js.map" type="application/javascript"></script> <script> function navbar_update(this_page){ $("#"+this_page+"_item").addClass('active'); $("#"+this_page+"_link").append(' <span class="sr-only">(current)</span>'); } <script> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-primary"> <a class="navbar-brand" href="index.php">AMP JAM Site</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li id="home_item" class="nav-item"> <a id="home_link" class="nav-link" href="index.php">Home</a> </li> <li id="list_item" class="nav-item"> <a id="list_link" class="nav-link" href="list.php">The List</a> </li> <li id="contact_item" class="nav-item"> <a id="contact_link" class="nav-link" href="form.php">Contact</a> </li> </ul> <ul id="right_navbar" class="navbar-nav ml-auto mr-5"> <?php session_start(); if(isset($_SESSION["user_id"])){ if($_SESSION["role"] > 0){ echo ' <li id="messages_item" class="nav-item"> <a id="messages_link" class="nav-link" href="messages.php">Messages</a> </li>'; } // end - if($_SESSION["role"] > 0) echo ' <li id="logout_item" class="nav-item"> <a id="logout_link" class="nav-link" href="logout.php">Log-Out</a> </li>'; }else{ echo ' <li id="login_item" class="nav-item"> <a id="login_link" class="nav-link" href="login.php">Log-In</a> </li>'; } // end - else if(isset($_SESSION["user_id"])) ?> </ul> </div> </nav>
(messages.php)<?php include("n413connect.php"); include("head.php"); $messages = array(); $sql = "SELECT * FROM `form_responses` ORDER BY timestamp DESC"; $result = mysqli_query($link, $sql); while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)){ $messages[] = $row; } ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <?php if(count($messages) > 0){ echo '<h1>Contact Form Messages</h1>'; }else{ echo '<h2>There are no messages at this time.</h2>'; } ?> </div> <!-- /.col-12 --> </div> <!-- /.row --> <?php if($_SESSION["role"] > 0){ foreach($messages as $message){ echo' <div class="row mt-3"> <div class="col-2"></div> <!-- spacer --> <div class="col-2">'.$message["name"].'<br/> <a href="mailto:'.$message["email"].'">'.$message["email"].'</a><br/> ['.$message["timestamp"].'] </div> <div class="col-6">'.$message["comment"].'</div> </div> <!-- /.row -->'; } //foreach }else{ echo' <div class="row mt-3"> <div class="col-12 text-center"><h3>You are not authorized to view the messages.</h3></div> </div> <!-- /.row -->'; } //else if ?> </div> <!-- /.container-fluid --> </body> <script> var this_page = "messages"; var page_title = 'AMP JAM Site | Messages'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
(users.sql)-- phpMyAdmin SQL Dump -- version 4.8.3 -- https://www.phpmyadmin.net/ -- -- Host: localhost:8889 -- Generation Time: Apr 18, 2020 at 06:25 PM -- Server version: 5.7.23 -- PHP Version: 7.2.10 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Database: `ampjam_db` -- -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE `users` ( `id` int(11) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` text NOT NULL, `role` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Indexes for dumped tables -- -- -- Indexes for table `users` -- ALTER TABLE `users` ADD PRIMARY KEY (`id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `users` -- ALTER TABLE `users` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
(login.php)<?php include("head.php"); ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-in</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <form method="POST" action="n413auth.php"> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div id="form-container" class="col-4"> User Name: <input type="text" id="username" name="username" class="form-control" value="" placeholder="Enter User Name" required/><br/> Password: <input type="password" id="password" name="password" class="form-control" value="" placeholder="Enter Password" required/><br/> <button type="submit" id="submit" class="btn btn-primary float-right">Submit</button> </div> <!-- /#form-container --> </div> <!-- /.row --> </form> </body> <script> var this_page = "login"; var page_title = 'AMP JAM Site | Login'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
(n413auth.php)<?php include("n413connect.php"); function sanitize($item){ global $link; $item = html_entity_decode($item); $item = trim($item); $item = stripslashes($item); $item = strip_tags($item); $item = mysqli_real_escape_string( $link, $item ); return $item; } $username = ""; $password = ""; if(isset($_POST["username"])) { $username = sanitize($_POST["username"]); } if(isset($_POST["password"])) { $password = sanitize($_POST["password"]); } $sql= "SELECT * FROM `users` WHERE username = '".$username."' AND password = '".$password."' LIMIT 1"; $result = mysqli_query($link, $sql); $row = mysqli_fetch_array($result, MYSQLI_BOTH); if($row){ session_start(); $_SESSION["user_id"] = $row["id"]; $_SESSION["role"] = $row["role"]; } include("head.php"); ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-in</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div class="col-4 text-center"> <?php if(isset($_SESSION["user_id"])){ echo '<h3>You are now Logged In.</h3>'; }else{ echo '<h3>The Log-In was not successful.</h3> <a href="login.php"><button class="btn btn-primary mt-5">Try Again</button></a>'; } ?> </div> <!-- /.col-4 --> </div> <!-- /.row --> </div> <!-- /.container-fluid --> </body> <script> var this_page = "login"; var page_title = 'AMP JAM Site | Login'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
(logout.php)<?php session_start(); unset($_SESSION); session_destroy(); include("head.php"); ?> <div class="container-fluid"> <div id="headline" class="row mt-5"> <div class="col-12 text-center"> <h2>Full Stack Amp Jam Log-out</h2> </div> <!-- /col-12 --> </div> <!-- /row --> <div class="row mt-5"> <div class="col-4"></div> <!-- spacer --> <div class="col-4 text-center"> <h3>You are now Logged Out.</h3> <a href="login.php"><button class="btn btn-primary mt-5">Log In</button></a> </div> <!-- /.col-4 --> </div> <!-- /.row --> </div> <!-- /.container-fluid --> </body> <script> var this_page = "logout"; var page_title = 'AMP JAM Site | Logout'; $(document).ready(function(){ document.title = page_title; navbar_update(this_page); }); //document.ready </script> </html>
If you want to download completed versions of the PHP scripts and image files, you can find them here.
Ready to take it to the next level? lets proceed to The PASSWORD!