Table of Contents
PHP Login Registration System with PDO Connection using SHA-256 Cryptographic Hash Algorithm to store Password
Things you should know before following this tutorial:
- PHP
- MySQL
- Bootstrap (optional)
If you’re a PHP beginner then yes, this tutorial is for you as well, just follow the steps carefully.
Here we going to develop a quick login registration system with PHP and PDO extension, by end of this tutorial you should be able to use PDO connection and be able to develop your own login and registration feature and include in your project.
Quick Note on Password Encryption:
`SHA-256 Cryptographic Hash Algorithm`is a one-way cryptographic function it cannot be decrypted back, so keep in mind hash is not an encryption. if you want more secure methods to store password, I suggest using `bcrypt` or `scrypt`. if your using PHP 5.5 version you can easily use new in built php functions `password_hash()` and `password_verify()`.
Let’s begin:
Step 1: Create Database and required tables:
Create Database or use existing and add following table:
CREATE TABLE `users` ( `user_id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` VARCHAR( 50 ) NOT NULL , `email` VARCHAR( 100 ) NOT NULL , `username` VARCHAR( 50 ) NOT NULL , `password` VARCHAR( 250 ) NOT NULL ) ENGINE = MYISAM ;
Step 3: Database Configuration file:
The basic need for every dynamic application is Database, let’s add new file called `database.php` this file is having PDO database connection script to use. you can add following script to the file, just don’t forgot to change connection variable as per your server setting.
`database.php`
<?php /** * iTech Empires Tutorial Script : PHP Login Registration system with PDO Connection * * File: Database Configuration */ // database Connection variables define('HOST', 'localhost'); // Database host name ex. localhost define('USER', 'root'); // Database user. ex. root ( if your on local server) define('PASSWORD', ''); // user password (if password is not set for user then keep it empty ) define('DATABASE', 'databasename'); // Database Database name function DB() { try { $db = new PDO('mysql:host='.HOST.';dbname='.DATABASE.'', USER, PASSWORD); return $db; } catch (PDOException $e) { return "Error!: " . $e->getMessage(); die(); } } ?>
Step 4: Design Login and Register Form:
I have added both the forms on `index.php` as this is just a demo, you can easily move them to the proper location for example you can create separate files for both the pages.
Also, for design we are using `bootstrap` here.
`login form:`
<div class="row"> <div class="col-md-5 well"> <h4>Login</h4> <?php if ($login_error_message != "") { echo '<div class="alert alert-danger"><strong>Error: </strong> ' . $login_error_message . '</div>'; } ?> <form action="index.php" method="post"> <div class="form-group"> <label for="">Username/Email</label> <input type="text" name="username" class="form-control"/> </div> <div class="form-group"> <label for="">Password</label> <input type="password" name="password" class="form-control"/> </div> <div class="form-group"> <input type="submit" name="btnLogin" class="btn btn-primary" value="Login"/> </div> </form> </div> </div>
`User registration form: `
<div class="row"> <div class="col-md-5 well"> <h4>Register</h4> <?php if ($register_error_message != "") { echo '<div class="alert alert-danger"><strong>Error: </strong> ' . $register_error_message . '</div>'; } ?> <form action="index.php" method="post"> <div class="form-group"> <label for="">Name</label> <input type="text" name="name" class="form-control"/> </div> <div class="form-group"> <label for="">Email</label> <input type="email" name="email" class="form-control"/> </div> <div class="form-group"> <label for="">Username</label> <input type="text" name="username" class="form-control"/> </div> <div class="form-group"> <label for="">Password</label> <input type="password" name="password" class="form-control"/> </div> <div class="form-group"> <input type="submit" name="btnRegister" class="btn btn-primary" value="Register"/> </div> </form> </div> </div>
Here is complete Code for index.php:
Note: Focus on PHP code from top section of index.php page below, I have started PHP code by starting the session and the using the Database connection file we were created in Step 3, after that I have Application library file which having Class and function, I will explain it in the next step.
<?php /* * Tutorial: PHP Login Registration system * * Page index.php * */ // Start Session session_start(); // Application library ( with DemoLib class ) require __DIR__ . '/lib/library.php'; $app = new DemoLib(); $login_error_message = ''; $register_error_message = ''; // check Login request if (!empty($_POST['btnLogin'])) { $username = trim($_POST['usernamea']); $password = trim($_POST['password']); if ($username == "") { $login_error_message = 'Username field is required!'; } else if ($password == "") { $login_error_message = 'Password field is required!'; } else { $user_id = $app->Login($username, $password); // check user login if($user_id > 0) { $_SESSION['user_id'] = $user_id; // Set Session header("Location: profile.php"); // Redirect user to the profile.php } else { $login_error_message = 'Invalid login details!'; } } } // check Register request if (!empty($_POST['btnRegister'])) { if ($_POST['name'] == "") { $register_error_message = 'Name field is required!'; } else if ($_POST['email'] == "") { $register_error_message = 'Email field is required!'; } else if ($_POST['username'] == "") { $register_error_message = 'Username field is required!'; } else if ($_POST['password'] == "") { $register_error_message = 'Password field is required!'; } else if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $register_error_message = 'Invalid email address!'; } else if ($app->isEmail($_POST['email'])) { $register_error_message = 'Email is already in use!'; } else if ($app->isUsername($_POST['username'])) { $register_error_message = 'Username is already in use!'; } else { $user_id = $app->Register($_POST['name'], $_POST['email'], $_POST['username'], $_POST['password']); // set session and redirect user to the profile page $_SESSION['user_id'] = $user_id; header("Location: profile.php"); } } ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="css/bootstrap.min.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-12"> <h2> PHP Login Registration System with PDO Connection using SHA-256 Cryptographic Hash Algorithm to store Password </h2> </div> </div> <div class="form-group"> Note: This is demo version from iTech Empires tutorials. </div> <div class="row"> <div class="col-md-5 well"> <h4>Register</h4> <?php if ($register_error_message != "") { echo '<div class="alert alert-danger"><strong>Error: </strong> ' . $register_error_message . '</div>'; } ?> <form action="index.php" method="post"> <div class="form-group"> <label for="">Name</label> <input type="text" name="name" class="form-control"/> </div> <div class="form-group"> <label for="">Email</label> <input type="email" name="email" class="form-control"/> </div> <div class="form-group"> <label for="">Username</label> <input type="text" name="username" class="form-control"/> </div> <div class="form-group"> <label for="">Password</label> <input type="password" name="password" class="form-control"/> </div> <div class="form-group"> <input type="submit" name="btnRegister" class="btn btn-primary" value="Register"/> </div> </form> </div> <div class="col-md-2"></div> <div class="col-md-5 well"> <h4>Login</h4> <?php if ($login_error_message != "") { echo '<div class="alert alert-danger"><strong>Error: </strong> ' . $login_error_message . '</div>'; } ?> <form action="index.php" method="post"> <div class="form-group"> <label for="">Username/Email</label> <input type="text" name="username" class="form-control"/> </div> <div class="form-group"> <label for="">Password</label> <input type="password" name="password" class="form-control"/> </div> <div class="form-group"> <input type="submit" name="btnLogin" class="btn btn-primary" value="Login"/> </div> </form> </div> </div> </div> </body> </html>
Step 5: Application Library file:
We are using library.php file in index.php folder, library file having few functions to handle request coming from index.php page, let’s have look on page below:
<?php /* * Tutorial: PHP Login Registration system * * Page: Application library * */ class DemoLib { /* * Register New User * * @param $name, $email, $username, $password * @return ID * */ public function Register($name, $email, $username, $password) { try { $db = DB(); $query = $db->prepare("INSERT INTO users(name, email, username, password) VALUES (:name,:email,:username,:password)"); $query->bindParam("name", $name, PDO::PARAM_STR); $query->bindParam("email", $email, PDO::PARAM_STR); $query->bindParam("username", $username, PDO::PARAM_STR); $enc_password = hash('sha256', $password); $query->bindParam("password", $enc_password, PDO::PARAM_STR); $query->execute(); return $db->lastInsertId(); } catch (PDOException $e) { exit($e->getMessage()); } } /* * Check Username * * @param $username * @return boolean * */ public function isUsername($username) { try { $db = DB(); $query = $db->prepare("SELECT user_id FROM users WHERE username=:username"); $query->bindParam("username", $username, PDO::PARAM_STR); $query->execute(); if ($query->rowCount() > 0) { return true; } else { return false; } } catch (PDOException $e) { exit($e->getMessage()); } } /* * Check Email * * @param $email * @return boolean * */ public function isEmail($email) { try { $db = DB(); $query = $db->prepare("SELECT user_id FROM users WHERE email=:email"); $query->bindParam("email", $email, PDO::PARAM_STR); $query->execute(); if ($query->rowCount() > 0) { return true; } else { return false; } } catch (PDOException $e) { exit($e->getMessage()); } } /* * Login * * @param $username, $password * @return $mixed * */ public function Login($username, $password) { try { $db = DB(); $query = $db->prepare("SELECT user_id FROM users WHERE (username=:username OR email=:username) AND password=:password"); $query->bindParam("username", $username, PDO::PARAM_STR); $enc_password = hash('sha256', $password); $query->bindParam("password", $enc_password, PDO::PARAM_STR); $query->execute(); if ($query->rowCount() > 0) { $result = $query->fetch(PDO::FETCH_OBJ); return $result->user_id; } else { return false; } } catch (PDOException $e) { exit($e->getMessage()); } } /* * get User Details * * @param $user_id * @return $mixed * */ public function UserDetails($user_id) { try { $db = DB(); $query = $db->prepare("SELECT user_id, name, username, email FROM users WHERE user_id=:user_id"); $query->bindParam("user_id", $user_id, PDO::PARAM_STR); $query->execute(); if ($query->rowCount() > 0) { return $query->fetch(PDO::FETCH_OBJ); } } catch (PDOException $e) { exit($e->getMessage()); } } }
A quick detail on the application lib page functions:
`Register()` – as name suggest this function is to create/add new user to the database
`isUsername()` – used to check username availability validation.
`isEmail()` – used to check email address availability validation.
`Login()` – used to get user login to the system by using username/email and password.
`UserDetails()` – to get the user details according to the specified ID.
Note: This is a better practice to use centralize application library if you’re working on core PHP, it helps to track functionality and gives us code re-usability and mainly important thing is it helps us to manage our code effectively.
Step 6: Profile Page:
I am using a demo profile page to redirect user after successfully login or user registration to say hello along with the logout button.
`profile.php:`
<?php /** * Tutorial: PHP Login Registration system * * Page : Profile */ // Start Session session_start(); // check user login if(empty($_SESSION['user_id'])) { header("Location: index.php"); } // Database connection require __DIR__ . '/database.php'; $db = DB(); // Application library ( with DemoLib class ) require __DIR__ . '/lib/library.php'; $app = new DemoLib(); $user = $app->UserDetails($_SESSION['user_id']); // get user details ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Profile</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="css/bootstrap.min.css"> </head> <body> <div class="container"> <div class="well"> <h2> Profile </h2> <h3>Hello <?php echo $user->name ?>,</h3> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur deserunt dolore fuga labore magni maxime, quaerat reiciendis tenetur? Accusantium blanditiis doloribus earum error inventore laudantium nesciunt quis reprehenderit ullam vel? </p> <a href="logout.php" class="btn btn-primary">Logout</a> </div> </div> </body> </html>
Step 7: Logout Page:
`logout.php:`
<?php /** * Tutorial: PHP Login Registration system * * Page : Logout */ // start session session_start(); // Destroy user session unset($_SESSION['user_id']); // Redirect to index.php page header("Location: index.php"); ?>
All done, try to run your code if you are following the steps or you can easily download complete source code use bellow link to download. you can also test live demo to get more understandings. let me know if you get any issues with this tutorial by using comment box below.
You can also read about how to create Login Registration system using `mysqli` extension: PHP Login Registration – State Management
Weldone! Add it do OnceBuilder
Thank you, we will think about it.
Besides the use of sha256 instead of PHP’s built in password functions there are a couple of problematic samples in this article that I wouldn’t want novices to pick up as good habits.
First, using constants for your database credentials is an unneeded global dependency for your DB() function. They really should be passed into DB as parameters. Consequently, DB() should be injected as a dependency to the DemoLib class, not pulled in from the global scope via `$db = DB()`.
Second, password should be uniquely salted not just hashed. Again, there’s a reason PHP added `password_hash`, just use it.
The way validation is handled, you can only ever return one error to the user at a time. So if someone forgets to put in a value for name and email, they’ll be submitting the form a second time.
The form should use a CSRF token to protect the form. Again, I understand this is for novices, but showing how to build a login form without one is dangerous.
Also, I just noticed that $_POST[‘name’] is saved to the database and later displayed with name ?>, which could be vulnerable to XSS since the output is not being escaped with html_entities.
I appreciate your feedback, above all the things is going to cover in upcoming tutorials.
Great! Although for #3 – you should never rely solely on clientside validation. You’ll still need to validate input with PHP (clients can misbehave or someone could do a POST to your form with using your HTML). For #5 – yes PDO with prepared statements guards you from SQL Injection attacks but if you’re storing what the user suppleis and then echo’ing without escaping, that’s a XSS vector.
Thank you for your tutorial. It was very helpful.
Hi, how would I go about redirecting the user to their profile page with “php?id=” in the address bar? Also, I’m curious if there is a way to share this link with other users?
Very nice tutorial but how i can do the same exactly with sqlite PDO????
Hello,
I would like to know how to secure my site against XSS attacks.
Hi Thank you for your tutorial, I get a problem with $db=DB(); it says undefined. I have separated user registration into another file and library in another file. Need your assistance if possible.
Why don’t you require or include database.php on the index.php file? With the current way your script is written, it’s impossible for the register / login to work.
I have an error on this login please help me!
this is my error: Fatal error: Uncaught Error: Call to undefined function DB() in C:\xampp\htdocs\login\lib\library.php:67 Stack trace: #0 C:\xampp\htdocs\login\index.php(54): DemoLib->isEmail(‘pobsina@gmail.c…’) #1 {main} thrown in C:\xampp\htdocs\login\lib\library.php on line 67
Hi, thank you for your tutorial. I have an error for DB() … it says it is undefined function. what should I do?
I want to learn PHP so can you help me my project title is book management system.
I am basically from Balochistan i am doing may BSCS form Balochistan University(UOB Quetta)
how to run this in phpmyadmin?
Hi there!
i have just purchased a login and register script using PDO, am geting an error when running..
can you help?
What is the error? send us error code. will you get fixed.
I also purchased and am getting this error every time… Fatal error: Call to a member function prepare() on string in E:\InetPub\wwwroot\intranet\login\lib\library.php on line 91. I’ve tried to fix it but no success so far.
whats the error ?
How to can I add my own css styles from websites diffrent?
Hello
I’m using your login system.
I want to thank you for it.
I work very well with him.
I would still like to be able to approve the registration.
You mean you want to verify user registration? if yes then here is the tutorial for you – User Account activation by email verification using PHP
Is this tutorial will run to ORACLE? Thanks
One of the most overlooked, but yet, most important options in these tutorials, is a forgot password link. I’m actually pretty good with most of PHP, except login and register systems. So, I always come to these tutorials when I need a good login system. Would be nice if they included a forgot password link.
Your login function is not working. copy pasted and yet it I can’t login. although the register function works only the login won’t
I have been using your login system for a long time. I need to know how to set up the use of two databases. Could you please help me?
To do this you should use a PHP Framework like Laravel, Laravel Provide a great way when it comes to handle multiple databases.