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 registration form to go with the login form that we created.

Before we get started there are some requirements you need for this tutorial, you need a web server running PHP 5 (or over), MySQL server, and MySQLi extension for PHP (usually enabled by default).

We recommend downloading and installing XAMPP if you're developing your projects on a local computer.

File Structure

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


1. Creating the Registration Form Design

You can either create your own registration form design or use the design below.

register.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Register</title>
		<style>
		.register-form {
			width: 300px;
			margin: 0 auto;
			font-family: Tahoma, Geneva, sans-serif;
		}
		.register-form h1 {
			text-align: center;
			color: #4d4d4d;
			font-size: 24px;
			padding: 20px 0 20px 0;
		}
		.register-form input[type="email"],
		.register-form input[type="password"],
		.register-form input[type="text"] {
			width: 100%;
			padding: 15px;
			border: 1px solid #dddddd;
			margin-bottom: 15px;
			box-sizing:border-box;
		}
		.register-form input[type="submit"] {
			width: 100%;
			padding: 15px;
			background-color: #535b63;
			border: 0;
			box-sizing: border-box;
			cursor: pointer;
			font-weight: bold;
			color: #ffffff;
		}
		</style>
	</head>
	<body>
		<div class="register-form">
			<h1>Register Form</h1>
			<form action="register.php" method="post">
				<input type="text" name="username" placeholder="Username" required>
				<input type="password" name="password" placeholder="Password" required>
				<input type="email" name="email" placeholder="Email" required>
				<input type="submit">
			</form>
		</div>
	</body>
</html>

You should now have something that will look like the below image when you load up the register.html file in your browser.

HTML and PHP Registration Form Design

The above code is a basic layout we need to register users on our website, as you can see with the form we have the username, password, and email fields, we also link our form to register.php which will come next. The form method is set to post which will allow us to send the form data to the server when the user clicks the submit button.


2. Registering Users with PHP

Now we need to create the registration file, this file will process the form fields, we will check for basic validation and insert the fields in to our database, if you didn't follow the previous login tutorial you will need to execute the following SQL statement:

CREATE DATABASE IF NOT EXISTS `phplogin` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `phplogin`;

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

INSERT INTO `accounts` (`id`, `username`, `password`, `email`) VALUES (1, 'test', '$1$zlnYwMy4$XJXe7it14YoWwr0lrK3M4.', 'test@test.com');

ALTER TABLE `accounts` ADD PRIMARY KEY (`id`);

ALTER TABLE `accounts` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;

register.php

I have included comments in the PHP script so you can understand what each part of the script does.

<?php
// Change this to your connection info.
$DB_HOST = 'localhost';
$DB_USER = 'root';
$DB_PASS = '';
$DB_NAME = 'phplogin';
// Try and connect using the info above.
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_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_errno);
}
// Now we check if the data was submitted, isset 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!<br><a href="register.html">Back</a>');
}
// 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!<br><a href="register.html">Back</a>');
}
// We need to check if the account with that username exists
if ($stmt = $mysqli->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!<br><a href="register.html">Back</a>';
	} else {
		// Username doesnt exists, insert new account
		if ($stmt = $mysqli->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!<br><a href="index.html">Login</a>';
		} else {
			echo 'Could not prepare statement!';
		}
	}
	$stmt->close();
} else {
	echo 'Could not prepare statement!';
}
$mysqli->close();
?>

That's basically all we need to do to register users on our website. The above code will check if the user has sent the form values, then we check if they are empty, and finally if the username doesn't exist in our database table we insert the new account.


3. Validation

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!<br><a href="register.html">Back</a>');
}

Invalid Characters Validation

if (preg_match('/[A-Za-z0-9]+/', $_POST['username']) == 0) {
    die ('Username is not valid!<br><a href="register.html">Back</a>');
}

Character Length Check

if (strlen($_POST['password']) > 20 || strlen($_POST['password']) < 5) {
	die ('Password must be between 5 and 20 characters long.<br><a href="register.html">Back</a>');
}


Implementing Account Activation

If you would like to implement account activation into your registration then read on.

The first thing we need to do is to go into phpMyAdmin and select the database we're using, in our case phplogin, you can either add the column activation_code to accounts or run the SQL statement below.

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

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

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

Change it to:

if ($stmt = $mysqli->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.

Search for:

echo 'You have successfully registered, you can now login!<br><a href="index.html">Login</a>';

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 direct link to our activate.php, remember to change the domain to your own domain name.

activate.php

Now we need to create our activation file, this file will check the email and code sent by the user, if they are valid their account will be activated.

<?php
// Change this to your connection info.
$DB_HOST = 'localhost';
$DB_USER = 'root';
$DB_PASS = '';
$DB_NAME = 'phplogin';
// Try and connect using the info above.
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_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_errno);
}
// First we check if the email and code exists...
if (isset($_GET['email'], $_GET['code'])) {
	if ($stmt = $mysqli->prepare('SELECT * FROM accounts WHERE email = ? AND activation_code = ? AND activation_code != 0')) {
		$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 = $mysqli->prepare('UPDATE accounts SET activation_code = ? WHERE email = ?')) {
				// 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('ss', $newcode, $_GET['email']);
				$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 account is valid the record will be updated in our database, the activation_code columns value will be changed to activated, and to check if the user has activated their account you can do something like:

if ($column['activation_code'] == 'activated') {
	// account is activated
} else {
	// account is not activated
}

Obviously, 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

You should now have a basic understanding of how a registration system works in 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 a 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!


Download Source