Apache Tutorial
Set up a Ubuntu/Apache cloud-based server


Sample Website

_______________________________________________

Introductory Comments

This is the best part! We will install a login and register web based system using a MySQL database.

This demo site will incorporate many of the tasks you will often do with your own website. You may need a login page. And you may need a page to register new users. I went out on the web and found a relatively simple code source to customize for this demo. The code is royalty and copyright free from the providers. Go to the CodeShack Secure Login System with PHP and MySQL to review the operational details and to learn new things. Be forewarned, their code is different than the code you will be installing. As I said, the code you see on this website is customized for your use on the VPS cloud server.

To fully function, this code needs a mail server connection. I'll work to add one in the future.

One thing is certain, this is a very useful training exercise to teach you some website basics. Enjoy.

_______________________________________________

Create File Structure

First, make sure you have completed the tutorial up to this lesson. You will need everything you have done so far to successfully complete this web page.

Open up FileZilla and navigate online to Your-Domain directory. Create the following file structure. It should look like this:

Demo File Structure

Create a similar structure on your desktop or wherever you can easily find the files. I use the name Demo as the top level for the web server. This would be the Your-Domain directory on the web server. It should be similar to this:

Demo Desktop File Structure

_______________________________________________

Create CSS File

Now, open up PSPad. We are going to create a CSS or cascading style sheet file.

Command: File | New file | CSS. Place the following code into this file after the /* CSS Document */ line:

*                                        { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif; font-size: 16px; }
body                                     { background-color: #435165; margin: 0; }
.login                                   { width: 400px; background-color: #ffffff; box-shadow: 0 0 9px 0 rgba(0, 0, 0, 0.3); margin: 100px auto; }
.login h1                                { text-align: center; color: #5b6574; font-size: 24px; padding: 20px 0 20px 0;	border-bottom: 1px solid #dee0e4; }
.login h2                                { text-align: center; color: #5b6574; font-size: 12px;	padding: 20px 0 20px 0; border-bottom: 1px solid #dee0e4; }
.login form                              { display: flex; flex-wrap: wrap; justify-content: center; padding-top: 20px; }
.login form label                        { display: flex; justify-content: center; align-items: center;	width: 50px; height: 50px; background-color: #3274d6; color: #ffffff; }
.login form input[type="password"], .login form input[type="text"] { width: 310px; height: 50px; border: 1px solid #dee0e4;	margin-bottom: 20px; padding: 0 15px; }
.login form input[type="submit"]         { width: 100%; padding: 15px; margin-top: 20px; background-color: #3274d6;	border: 0; cursor: pointer; font-weight: bold; color: #ffffff; transition: background-color 0.2s; }
.login form input[type="submit"]:hover   { background-color: #2868c7; transition: background-color 0.2s; }
.navtop                                  { background-color: #2f3947; height: 60px;	width: 100%; border: 0; }
.navtop div                              { display: flex; margin: 0 auto; width: 1000px; height: 100%; }
.navtop div h1, .navtop div a            { display: inline-flex; align-items: center; }
.navtop div h1                           { flex: 1; font-size: 24px; padding: 0; margin: 0;	color: #eaebed; font-weight: normal; }
.navtop div a                            { padding: 0 20px; text-decoration: none; color: #c1c4c8; font-weight: bold; }
.navtop div a i                          { padding: 2px 8px 0 0; }
.navtop div a:hover                      { color: #eaebed; }
body.loggedin                            { background-color: #f3f4f7; }
.content                                 { width: 1000px; margin: 0 auto; }
.content h2                              { margin: 0; padding: 25px 0; font-size: 22px; border-bottom: 1px solid #e0e0e3; color: #4a536e; }
.content > p, .content > div             { box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1); margin: 25px 0; padding: 25px;	background-color: #fff; }
.content > p table td, .content > div table td { padding: 5px; }
.content > p table td:first-child, .content > div table td:first-child { font-weight: bold;	color: #4a536e;	padding-right: 15px; }
.content > div p                         { padding: 5px; margin: 0 0 10px 0; }
.content1                                { width: 1000px; margin: 0 auto; justify-content: space-between; }
.content1 h2                             { margin: 0; padding: 25px 0; font-size: 22px; border-bottom: 1px solid #e0e0e3; color: #4a536e; }
.content1 > p, .content > div            { box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1); margin: 25px 0; padding: 25px;	background-color: #fff; }
.content1 > p table td, .content > div table td { padding: 5px; }
.content1 > p table td:first-child, .content > div table td:first-child { font-weight: bold; color: #4a536e; padding-right: 15px; }
.content1 > div p                        { padding: 5px; margin: 0 0 10px 0; }
.register                                { width: 400px; background-color: #ffffff; box-shadow: 0 0 9px 0 rgba(0, 0, 0, 0.3); margin: 100px auto; }
.register h1                             { text-align: center; color: #5b6574; font-size: 24px; padding: 20px 0 20px 0; border-bottom: 1px solid #dee0e4; }
.register h2                             { text-align: center; color: #5b6574; font-size: 12px; padding: 20px 0 20px 0;	border-bottom: 1px solid #dee0e4; }
.register form                           { display: flex; flex-wrap: wrap; justify-content: center; padding-top: 20px; }
.register form label                     { display: flex; justify-content: center; align-items: center; width: 50px; height: 50px; background-color: #3274d6; color: #ffffff; }
.register form input[type="password"], .register form input[type="text"], .register form input[type="email"] { width: 310px; height: 50px; border: 1px solid #dee0e4; margin-bottom: 20px; padding: 0 15px; }
.register form input[type="submit"]      { width: 100%; padding: 15px; margin-top: 20px; background-color: #3274d6; border: 0; cursor: pointer; font-weight: bold; color: #ffffff; transition: background-color 0.2s; }
.register form input[type="submit"]:hover {	background-color: #2868c7; transition: background-color 0.2s; }

Save the file in the css folder with the name d-r-style.css and now create the HTML files needed to make this work properly.

_______________________________________________

A D V E R T I S E M E N T

_______________________________________________

HTML Files

Create index.html

Create an HTML file in PSPad. Command: File | New file | HTML. Erase all the lines you see. Place the following code into this file:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Login via MySQL</title>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
  <link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="login">
<h1>Login</h1>
<h2><div><a href="register.html"><i class="fas fa-sign-out-alt">&nbsp;&nbsp;&nbsp;</i>Go to Register</a></div></h2>
  <form action="authenticate.php" method="post">
      <label for="username">
         <i class="fas fa-user"></i>
	  </label>
	  <input type="text" name="username" placeholder="Username" id="username" required>
	  <label for="password">
		 <i class="fas fa-lock"></i>
	  </label>
      <input type="password" name="password" placeholder="Password" id="password" required>
	  <input type="submit" value="Login">
  </form>
</div>
</body>
</html>

Save the file as index.html in the phplogin directory on your desktop.

_______________________________________________

Create register.html

Create another html file and save it as register.html in the phplogin directory:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Login via MySQL</title>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
  <link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="register">
  <h1>Register</h1>
  <h2><div><a href="index.html"><i class="fas fa-sign-out-alt">&nbsp;&nbsp;&nbsp;</i>Go to Login</a></div></h2>            
  <form action="register.php" method="post" autocomplete="off">
	  <label for="username">
	     <i class="fas fa-user"></i>
	  </label>
	  <input type="text" name="username" placeholder="Username" id="username" required>
	  <label for="password">
					<i class="fas fa-lock"></i>
				</label>
				<input type="password" name="password" placeholder="Password" id="password" required>
				<label for="email">
					<i class="fas fa-envelope"></i>
				</label>
				<input type="email" name="email" placeholder="Email" id="email" required>
				<input type="submit" value="Register">
  </form>
</div>
</body>
</html>

_______________________________________________

A D V E R T I S E M E N T

_______________________________________________

PHP Files

Now it's time to create five PHP files. Don't worry, we are almost done. Go to PSPad, create each file and save it in the phplogin directory.

Use the command: File | New file | PHP. Erase all the lines already in that new file.

Create home.php

Place the following code into the home.php file:

<?php
// We need to use sessions, so you should always start sessions using the below code.
session_start();
// If the user is not logged in redirect to the login page...
if (!isset($_SESSION['loggedin'])) {
	header('Location: index.html');
	exit;
}
?>

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Home Page</title>
		<link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
		<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
	</head>
	<body class="loggedin">
		<nav class="navtop">
			<div>
				<h1>Website Title</h1>  /* Insert yours here. */
				<a href="profile.php"><i class="fas fa-user-circle"></i>Profile</a>
				<a href="logout.php"><i class="fas fa-sign-out-alt"><</i>Logout</a>
			</div>
		</nav>
		<div class="content">
			<h2>Home Page</h2>
			<p>Welcome back, <?=$_SESSION['name']?>!</p>
		</div>
	</body>
</html>

Create authenticate.php

Create the authenticate.php file and place this code inside. Do not change anything:

<?php
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'demo';
$DATABASE_PASS = '4$f5bJ&6z#xaQw2*9^5C%10LM^g';
$DATABASE_NAME = 'phplogin';
//  Only if you need to chase errors:
//ini_set('display_errors',1); 
//error_reporting(E_ALL);
//    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    try{
        $con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
    }catch (Exception $e){
        echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
              <link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
              <div class="content"><p>' . 'Database login failed. Check your database credentials!' . '&nbsp;&nbsp;&nbsp;<a href="index.html">
              <i class="fas fa-sign-out-alt"></i>Login</a></p></div>';
        //echo $e->getMessage();  Use to find MySQL errors only
        exit;
    }

// Now we check if the data from the login form was submitted, isset() will check if the data exists.
/*   if ( !isset($_POST['username'], $_POST['password']) ) { */
    if (!filter_input(INPUT_POST, "username") OR !filter_input(INPUT_POST, "password")) {
	// Could not get the data that should have been sent.
	exit('Please fill both the username and password fields!');
}

// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
   if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
	// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
    $stmt->bind_param('s', filter_input(INPUT_POST, 'username'));
	$stmt->execute();
	// Store the result so we can check if the account exists in the database.
	$stmt->store_result();
if ($stmt->num_rows > 0) {
	$stmt->bind_result($id, $password);
	$stmt->fetch();
	// Account exists, now we verify the password.
	// Note: remember to use password_hash in your registration file to store the hashed passwords.
    if (password_verify(filter_input(INPUT_POST, 'password'), $password)) {
		// Verification success! User has logged-in!
		// Create sessions, so we know the user is logged in, they basically act like cookies but remember the data on the server.
		session_regenerate_id();
		$_SESSION['loggedin'] = TRUE;
		$_SESSION['name'] = filter_input(INPUT_POST, 'username'); 
		$_SESSION['id'] = $id;
		/* echo 'Welcome ' . $_SESSION['name'] . '!'; */  /* removed to redirect to home.php */
        header('Location: home.php');  
	} else {
		// Incorrect password
		echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
        <link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
        <div class="content"><p>Incorrect username and/or Password!   <a href="index.html"><i class="fas fa-sign-out-alt"></i>Logout</a></p></div>';
	}
} else {
	// Incorrect username
	echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
        <link href="../css/d-r-style.css" rel="stylesheet" type="text/css">
        <div class="content"><p>Incorrect Username and/or password!   <a href="index.html"><i class="fas fa-sign-out-alt"></i>Logout</a></p></div>';
}

	$stmt->close();
}
?>

Create logout.php

Create the logout.php file and place this code inside:

<?php
session_start();
session_destroy();
// Redirect to the login page:
header('Location: index.html');
?>

Create profile.php

Create the profile.php file and place this code inside. Do not change anything:

<?php
// We need to use sessions, so you should always start sessions using the below code.
session_start();
// If the user is not logged in redirect to the login page...
if (!isset($_SESSION['loggedin'])) {
	header('Location: index.html');
	exit;
}
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'demo';
$DATABASE_PASS = '4$f5bJ&6z#xaQw2*9^5C%10LM^g';
$DATABASE_NAME = 'phplogin';
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
	exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// We don't have the password or email info stored in sessions so instead we can get the results from the database.
$stmt = $con->prepare('SELECT password, email FROM accounts WHERE id = ?');
// In this case we can use the account ID to get the account info.
$stmt->bind_param('i', $_SESSION['id']);
$stmt->execute();
$stmt->bind_result($password, $email);
$stmt->fetch();
$stmt->close();
?>

Create register.php

Create the register.php file and place this code inside. Do not change anything:

<?php
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'demo';
$DATABASE_PASS = '4$f5bJ&6z#xaQw2*9^5C%10LM^g';
$DATABASE_NAME = 'phplogin';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
	// If there is an error with the connection, stop the script and display the error.
  /*  echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
        <link href="../css/d-r-style.css" rel="stylesheet" type="text/css"><div class="content"><p>Failed to connect to MySQL:&nbsp;&nbsp;&nbsp;<a href="register.html"><i class="fas fa-sign-out-alt"></i>Register</a></p></div>';
        exit;  */
	exit('Failed to connect to MySQL: ' . mysqli_connect_error()); 
}

// Now we check if the data was submitted, isset() function will check if the data exists.
if (!isset($_POST['username'], $_POST['password'], $_POST['email'])) {
	// Could not get the data that should have been sent.
	exit('Please complete the registration form!');
}
// Make sure the submitted registration values are not empty.
if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['email'])) {
	// One or more values are empty.
	exit('Please complete the registration form');
}

// Email Validation
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
	exit('Email is not valid!');
}

// Invalid Characters Validation
if (preg_match('/^[a-zA-Z0-9]+$/', $_POST['username']) == 0) {
    exit('Username is not valid!');
}

// Character Length Check
if (strlen($_POST['password']) > 20 || strlen($_POST['password']) < 5) {
	exit('Password must be between 5 and 20 characters long!');
}

// We need to check if the account with that username exists.
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
	// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
	$stmt->bind_param('s', $_POST['username']);
	$stmt->execute();
	$stmt->store_result();
	// Store the result so we can check if the account exists in the database.
	if ($stmt->num_rows > 0) {
		// Username already exists
		echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
        <link href="../css/d-r-style.css" rel="stylesheet" type="text/css"><div class="content"><p>Username exists, please choose another!&nbsp;&nbsp;&nbsp;<a href="register.html"><i class="fas fa-sign-out-alt"></i>Register</a></p></div>';
	} else {
		// Insert new account
        // Username doesn't exist, insert new account
/*if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) { */
  if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email, activation_code) VALUES (?, ?, ?, ?)')) {
	// We do not want to expose passwords in our database, so hash the password and use password_verify when a user logs in.
	$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
/*	$stmt->bind_param('sss', $_POST['username'], $password, $_POST['email']); */
    $uniqid = uniqid();
    $stmt->bind_param('ssss', $_POST['username'], $password, $_POST['email'], $uniqid);
	$stmt->execute();
/*	echo 'You have successfully registered, you can now login!'; */
$from    = 'noreply@apachetutorial.com';
$subject = 'Account Activation Required';
$headers = 'From: ' . $from . "\r\n" . 'Reply-To: ' . $from . "\r\n" . 'X-Mailer: PHP/' . phpversion() . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-Type: text/html; charset=UTF-8' . "\r\n";
// Update the activation variable below
$activate_link = 'https://www.apachetutorial.com/phplogin/activate.php?email=' . $_POST['email'] . '&code=' . $uniqid;
$message = '<p>Please click the following link to activate your account: <a href="' . $activate_link . '">' . $activate_link . '</a></p>';
mail($_POST['email'], $subject, $message, $headers);
echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"><link href="../css/d-r-style.css" rel="stylesheet" type="text/css"><div class="content"><p>Please check your email to activate your account!&nbsp;&nbsp;&nbsp;<a href="index.html"><i class="fas fa-sign-out-alt"></i>Login</a></p></div>';
} else {
	// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
	echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"><link href="../css/d-r-style.css" rel="stylesheet" type="text/css"><div class="content"><p>Could not prepare statement!&nbsp;&nbsp;&nbsp;<a href="register.html"><i class="fas fa-sign-out-alt"></i>Register</a></p></div>';
}
	}
	$stmt->close();
} else {
	// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
	echo '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"><link href="../css/d-r-style.css" rel="stylesheet" type="text/css"><div class="content"><p>Could not prepare statement!&nbsp;&nbsp;&nbsp;<a href="register.html"><i class="fas fa-sign-out-alt"></i>Register</a></p></div>';
}
$con->close();
?>

_______________________________________________

A D V E R T I S E M E N T

_______________________________________________

SQL to Set Up MySQL Database

We need to create a file that will properly set up our MySQL database for this demo. Use the command: File | New file | SQL (MySQL). Place the following code into the phplogin.sql file:

CREATE DATABASE phplogin;

USE phplogin;

CREATE TABLE IF NOT EXISTS `accounts` (
    `id` int NOT NULL AUTO_INCREMENT,
    `username` varchar(50) NOT NULL,
    `password` varchar(255) NOT NULL,
    `email` varchar(100) NOT NULL,
    `activation_code` varchar(50) DEFAULT '',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

INSERT INTO `accounts` (`id`, `username`, `password`, `email`) VALUES (1, 'test', '$2y$10$SfhYIDtn.iOuCW7zfoFLuuZHX6lja4lF4XA4JqNmpiH/.P3zB8JCa', 'test@test.com');

USE mysql;

CREATE USER 'demo'@'localhost' IDENTIFIED BY '4$f5bJ&6z#xaQw2*9^5C%10LM^g';

GRANT  INSERT, UPDATE, DELETE, SELECT ON phplogin.* TO 'demo'@'localhost'; 

FLUSH PRIVILEGES;

_______________________________________________

That's all of the files. You need to upload all of them except the SQL file to your server. Use FileZilla and drag them from your desktop folder location to the online website directory.

The css directory should look like this:

Demo CSS File Structure

The phplogin directory should look like this:

Demo phplogin File Structure

_______________________________________________

Import the SQL File to Your MySQL Server

The SQL file we made will save you some time in constructing the database. Simply uploading it with phpMyAdmin and running it within the server will automatically set up the database.

First, access your phpMyAdmin page. As a reminder, open a new tab in Nightly. Enter your URL. Add the /my-phrase you created to access phpMyAdmin after the URL. It should look like this: Your URL/my-phrase. Press Enter. You'll see the phpMyAdmin login screen. Log into the service.

In the top of the window, select Import. Click Browse and search for your phplogin.sql file. After you find it and return to this screen, select the GO button. If you don't see the GO button, scroll the page down to find it.

The query will finish momentarily. You will see all green response messages in the phpMyAdmin window. This is good. To test your new webpage, open a new tab in Nightly. Enter Your URL/phplogin. If you are successful, you will see this:

Demo CSS File Structure

You can test it immediately by entering test for the username and password. You will see a different webpage. This would be the page you would want users to see after they successfully logged into the server. Designing such a page is a topic for another time.

That's it. I hope you enjoyed this trek into cyberspace. There is more to learn. I'll add to your knowledge in the future. But for now, that's it!

_______________________________________________


COMMENTS - Sample domain


Leave a comment.
Moderator approval may be required before posting.


Total Views of this Page: 410

_______________________________________________

Valid HTML Valid CSS!

_______________________________________________

Rocket! Rocket! Rocket!

_______________________________________________

If You Like This:

PayPal Pixel

I may make affiliate fees from services you select on this website.
Thank you!
©1998-2023 RocketRanch


x
This website is using cookies.   More info. That's Fine
Welcome again, you previously approved our cookie policy.