HTML CSS JavaScript jQuery PHP MySQL

Secure Registration System with PHP and MySQL

Updated on by David Adams

Secure Registration System with PHP and MySQL

This tutorial is a follow up to our previous tutorial Secure Login System with PHP and MySQL, we'll be creating a secure registration form with basic validation.

1. Getting Started

There are a few steps we need to take before we create our secure login system, we need to set up our web server environment and make sure we have the required extensions enabled.

1.1. Requirements

  • If you haven't got a local web server setup you should download and install XAMPP.
  • By default, XAMPP will use the latest version of PHP, but if you're are using an older version, make sure to install PHP 5.4+ (includes the MySQLi extension).

1.2. What You Will Learn in this Tutorial

  • Form Design — Design a registration form with HTML and CSS.
  • Prepared SQL Queries — How to prepare SQL queries to prevent SQL injection and insert new records into a MySQL database.
  • Basic Validation — Validating form data that is sent to the server (username, password, and email).

1.3. File Structure & Setup

We now need to start our web server and create the files and folders we're going to use for our registration system.

  • Open XAMPP Control Panel
  • Next to the Apache module click Start
  • Next to the MySQL module click Start
  • Navigate to XAMPPs installation folder (C:\xampp)
  • Open the htdocs folder
  • Create the following folders and files:

File Structure

\-- phplogin
  |-- register.html
  |-- style.css
  |-- register.php
  |-- activate.php (optional)

Each file will contain the following:

  • register.html — Registration form created with HTML and CSS, we don't need to use PHP in this file so we can just save it as HTML.
  • style.css — The stylesheet for our secure registration form.
  • register.php — Validate form data and insert a new account in the MySQL database.
  • activate.php — Activate the users account with a unique code.

2. Creating the Registration Form Design

We need a registration form so the users can input their account information for the registration process, for the design we only need to use HTML and CSS.

Edit register.html and insert the following code:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Register</title>
		<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
	</head>
	<body>
		<div class="register">
			<h1>Register</h1>
			<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>

Navigate to http://localhost/phplogin/register.html, our registration form will look like the following:

http://localhost/phplogin/register.html
Basic HTML Registration Form Layout

Pretty basic for a registration form, now let's add some CSS, edit style.css and insert the following:

* {
  	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;
  	-webkit-font-smoothing: antialiased;
  	-moz-osx-font-smoothing: grayscale;
}
body {
  	background-color: #435165;
  	margin: 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 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;
}

We need to include our stylesheet in our index.html file, copy and paste the following code to the head section:

<link href="style.css" rel="stylesheet" type="text/css">

And now our registration form will look like the following:

http://localhost/phplogin/register.html
Awesome HTML Registration Form Layout

Let's narrow down the form so we can get a better understanding on what's going on.

  • Form — we need to use both the action and post attributes, the action attribute will be set to the registration file. When the form is submitted, the form data will be sent to the registration file for processing. The method is to post, this will allow us to process the form data.
    • Input (text/password/email) — We need to name our form fields so the server can recognize them, so if we set the value of the attribute name to the username, we can use the post variable in our registration file to get the data, like this: $_POST['username'].
    • Input (submit) — On click the form data will be sent to our registration file.

That's basically all we need to do on the client side, next step is to set up the database and create the registration file with PHP.

3. Creating the Database and setting-up Tables

You can skip this step if you followed the Secure Login System Tutorial.

For this part, you will need to access your MySQL database, either using phpMyAdmin or your preferred MySQL database management application.

If you're using phpMyAdmin follow these instructions:

  • Navigate to: http://localhost/phpmyadmin/
  • Click the Databases tab at the top
  • Under Create database, type in phplogin in the text box
  • Select utf8_general_ci as the collation
  • Click Create

You can use your own database name, but for this tutorial, I'll use phplogin.

What we need now is an accounts table, this table will store all the accounts (usernames, passwords, emails, etc).

Click the database on the left side panel (phplogin) and execute the following SQL statement:

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

On phpMyAdmin this should look like:

http://localhost/phpmyadmin/
phpMyAdmin Accounts Table

The above SQL statement code will create the accounts table with the columns id, username, password, and email.

4. Registering Users with PHP & MySQL

Now we need to create the registration file, this file will process the form fields, the code will check for basic validation and insert the new account into our database.

The first thing we need to do is to connect to our database, edit the register.php file and insert the following:

<?php
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$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.
	die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}

You will need to change the database variables if your credentials are different.

Next, we can add basic validation to make sure the user entered their details and check for empty variables.

// 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.
	die ('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.
	die ('Please complete the registration form');
}

Now we need to check if the account already exists, we can check this by selecting a record from our accounts table with the same username that the user has given, you can also add the email field so the user cannot register with same email address multiple times.

// 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 'Username exists, please choose another!';
	} else {
		// Insert new account
	}
	$stmt->close();
} else {
	// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
	echo 'Could not prepare statement!';
}
$con->close();
?>

Replace:

// Insert new account

With:

// Username doesnt exists, insert new account
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) 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']);
	$stmt->execute();
	echo 'You have successfully registered, you can now login!';
} else {
	// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
	echo 'Could not prepare statement!';
}

This will insert a new account in our database table.

Remember in our Login System we used the password_verify function? As you can see in the code above we use the password_hash function, this allows us to encrypt user's passwords — adding the extra security layer for passwords will prevent your users passwords from being exposed if for somehow your database becomes vulnerable.

That's basically all we need to do to register users on our website.

5. Validating Form Data

We already have basic validation in our PHP script but what if we want to check if the email is actually an email or if the usernames and passwords should be a certain amount of characters long, you can do that with the codes below, just add them in the register.php file before the following line:

if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {

Email Validation

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

Invalid Characters Validation

if (preg_match('/[A-Za-z0-9]+/', $_POST['username']) == 0) {
    die ('Username is not valid!');
}

Character Length Check

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

You should always implement your own validation, these are just basic examples to simplify the registration process.

6. Implementing Account Activation

The account activation system will send an email to the user with the activation link when the user has registered.

The first thing we need to do is to go into phpMyAdmin and select our database, in our case this would be phplogin, you can either add the column activation_code to the accounts table or execute the SQL statement below.

ALTER TABLE accounts ADD activation_code varchar(50) DEFAULT ''

Now we need to edit our register.php file, search for this line of code:

if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {

Replace with:

if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email, activation_code) VALUES (?, ?, ?, ?)')) {

Search for:

$stmt->bind_param('sss', $_POST['username'], $password, $_POST['email']);

Replace with:

$uniqid = uniqid();
$stmt->bind_param('ssss', $_POST['username'], $password, $_POST['email'], $uniqid);

The $uniqud variable will generate a unique ID that we'll use for our activation code, this will be sent to the user's email address.

Search for:

echo 'You have successfully registered, you can now login!';

Replace with:

$from    = 'noreply@yourdomain.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";
$activate_link = 'http://yourdomain.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 'Please check your email to activate your account!';

What this code will do is send the registered user an email with the account activation code, sending them a link to our activate.php file, you need to change both $from and $activate_link variables.

Now we need to create the activation file, this file will check the email and code for verification, the user's account will be activated if the code is valid.

Edit/create activate.php and insert the following code:

<?php
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$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.
	die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// First we check if the email and code exists...
if (isset($_GET['email'], $_GET['code'])) {
	if ($stmt = $con->prepare('SELECT * FROM accounts WHERE email = ? AND activation_code = ?')) {
		$stmt->bind_param('ss', $_GET['email'], $_GET['code']);
		$stmt->execute();
		// Store the result so we can check if the account exists in the database.
		$stmt->store_result();
		if ($stmt->num_rows > 0) {
			// Account exists with the requested email and code.
			if ($stmt = $con->prepare('UPDATE accounts SET activation_code = ? WHERE email = ? AND activation_code = ?')) {
				// Set the new activation code to 'activated', this is how we can check if the user has activated their account.
				$newcode = 'activated';
				$stmt->bind_param('sss', $newcode, $_GET['email'], $_GET['code']);
				$stmt->execute();
				echo 'Your account is now activated, you can now login!<br><a href="index.html">Login</a>';
			}
		} else {
			echo 'The account is already activated or doesn\'t exist!';
		}
	}
}
?>

If the code is valid the user's account will be updated in our database, the value of the activation_code column will be changed to activated, and to check if the user has activated their account in our code (home page, profile page, etc) you can do something like this:

if ($account['activation_code'] == 'activated') {
	// account is activated
	// Display home page etc
} else {
	// account is not activated
	// redirect user or display an error
}

You will need to connect to your MySQL database and select the user.

Also, take note PHP mail function will only work if your computer or server supports it. If it doesn't send an email check your configuration or install a mail server such as Postfix.

Conclusion

Congratulations you've successfully created a Login System (if you followed the previous tutorial) and registration system with PHP and MySQL, feel free to use the codes above and adapt them for your own projects.

Remember this is just a secure base that you should work from, change or add validation, and implement your own template.

If you would like more of this tutorial series feel free to drop a comment and suggest to us what we could do next.

Enjoy coding!

If you would like to support us consider purchasing a package below, this will greatly help us create more tutorials and keep our server up and running.

Basic

Advanced

Source code
Database SQL file
Secure login & registration system
Home page
Profile page
Activate account feature
Edit profile page
Remember me feature
AJAX integration
SCSS file
Commented code
Free updates
Free support (bugs and minor issues)
* Payments are processed with PayPal.
* Advanced package also includes the basic package.
* Limited time sale.

$5.00 $10.00

Buy Now

$15.00 $20.00

Buy Now