How to create a secure user login with PHP and MySQL
Almost all modern web applications contain a login of some description. Whether you give your visitors benefits from being a registered user or run an online store, a login form is essential. This article describes one of the many ways to implement this facility using PHP and MySQL. The login process checks for an invalid email address or incorrectly entered password and uses user data stored in a MySQL database.
This tutorial uses the following three files. You can download the complete package in ZIP format if you prefer to get straight in.
- form.htm - contains the login form
- process.php - processes the login details and validate user
- tblUser.sql - database schema for storing user data
The Database
The MySQL database schema (structure) is shown below. Create the table and add some test data to use when testing the form.
CREATE TABLE `tblUser` ( `fldUserID` int(10) unsigned NOT NULL auto_increment, `fldEmail` varchar(100) NOT NULL default '', `fldPassword` varchar(100) NOT NULL default '', PRIMARY KEY (`fldUserID`) );
The Form
The login form itself contains a field for both email address and password. We shall name the fields ‘e’ and ‘p’ respectively. Try to avoid naming password fields ‘password’ if you’re not using a secure connection, as it can be easily identified as a password if the data is intercepted in transit.
<form name="login" action="process.php" method="post"> <label for="e">E-mail address: </label><br /> <input type="text" name="e" id="e" maxlength="100" /> <br /> <label for="p">Password: </label><br /> <input type="password" name="p" id="p" maxlength="100" /> <br /> <input type="submit" value="Login" /> </form>
The Script
At the start of your script connect to your MySQL database. Insert your database connection settings as required.
<?php
$hostname = "YOUR HOSTNAME";
$databasename = "YOUR DATABASE NAME";
$username = "YOUR USERNAME";
$dbpassword = "YOUR PASSWORD";
$db = mysql_connect($hostname,$username,$dbpassword) or die("could not connect to database");
mysql_select_db($databasename);
?>
Define your variables for e-mail address and password.
$email = $_POST["e"]; $password = $_POST["p"];
Check the data is inputted from the form correctly prior to validating the user with the database. This can save time and server resources for larger volume websites. When an error occurs you can re-direct the user to a different page and display an appropriate error message. (Line wraps marked » -Ed.)
if (!$email){
#ERROR - you have not entered an email address
#Display appropriate error message
}
if (!$password){
#ERROR - you have not entered a password
#Display appropriate error message
}
if(!eregi("^[_&a-z0-9-]+(.[_&a-z0-9-]+)*@[a-z0-9-]+ »
(.[a-z0-9-]+)*(.[a-z]{2,3})$", $email)) {
#ERROR - your email address is not in the correct format
#Display appropriate error message
}
Now validate the user’s login details with the database. If we just select the e-mail address from the database it gives us the option to determine if the e-mail address was incorrect or the password was entered incorrectly. An appropriate error message can then be sent back to the user. In this example the password check is case sensitive.
Notice the use of the PHP function mysql_real_escape_string(). This function is used to prevent SQL injection attacks and should be used on all variables (as a result of user input).
$query = "SELECT * FROM tblUser WHERE fldEmail='".mysql_real_escape_string($email)."'";
$result = mysql_db_query ("$databasename", $query) or die("could not retrieve record");
$myrow = mysql_fetch_array($result);
if (!$myrow){
#ERROR - email address not found
#Display appropriate error message
}
if ($myrow["fldPassword"] !== $password){
#ERROR - incorrect password for email address
#Display appropriate error message
}
#LOGIN SUCCESS
If the login is successful you can start a session and send the user to a new page. You may also wish to encrypt the password in the database using the MD5 hash feature in PHP as an added security measure, and set a cookie to remember the e-mail address for the next time the visitor returns to the login form.

Thank you for the information. I have downloaded the files and changed my Mysql database.
What do I do with the files? Put them in my root?
How do I change the code to send the user to the page I want?
I have put the form code on the page I want it on, is this correct?
Please help me fix this.
That’s correct - the files can go in the root or any folder on the server. To send the user to a page use the following code:
header(”Location: http://www.mydomain.com/page.htm“);
break;
I hope you find this information useful. Please post any further questions…
My form now sends the user to the home page whether the form is filled out our not. It isn’t checking anything and even accepts nonsense characters. What should I do. Is there something I’m missing?
Hi Andrew,
Can you send me your code and I’ll take a look at it to see if there’s anything obvious missing? Please e-mail it to the address on our contact page.
Thanks,
Here is the code, thanks for looking.
#——————————————–
#CONNECT TO MYSQL DATABASE
#——————————————–
$hostname = “localhost”;
$databasename = “70526″;
$username = “70526″;
$dbpassword = “012201″;
$db = mysql_connect($hostname,$username,$dbpassword) or die(”could not connect to database”);
mysql_select_db($databasename);
#——————————————–
#DEFINE VARIABLES
#——————————————–
$email = $_POST["e"];
$password = $_POST["p"];
#——————————————–
#CHECK DATA
#——————————————–
if (!$email){
#ERROR - you have not entered an email address
#Display appropriate error message
}
if (!$password){
#ERROR - you have not entered a password
#Display appropriate error message
}
if(!eregi(”^[_&a-z0-9-]+(.[_&a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$”, $email)) {
#ERROR - your email address is not in the correct format
#Display appropriate error message
}
#——————————————–
#VALIDATE THE LOGIN DETAILS
#——————————————–
$query = “SELECT * FROM tblUser WHERE fldEmail=’”.mysql_real_escape_string($email).”‘”;
$result = mysql_db_query (”$databasename”, $query) or die(”could not retrieve record”);
$myrow = mysql_fetch_array($result);
if (!$myrow){
#ERROR - email address not found
#Display appropriate error message
}
if ($myrow["fldPassword"] !== $password){
#ERROR - incorrect password for email address
#Display appropriate error message
}
#——————————————–
#LOGIN SUCCESSFUL
#——————————————–
header(”Location: http://affiliatedcommerce.com/home.html“);
break;
?>
Hi Andrew,
You need to put some code where the #ERROR comments occur. The # signifies a comment and it not actioned by PHP. You could use the following code to send the user to an error page informing them of the error:
header(”Location: http://affiliatedcommerce.com/error_email.html“);
break;
..for the invalid e-mail address check. I hope this helps.
Hi Andrew,
You need to put some code where the #ERROR comments occur. The # signifies a comment and it not actioned by PHP. You could use the following code to send the user to an error page informing them of the error:
..for the invalid e-mail address check. I hope this helps.
Okay, sorry to be a bother, I think I’m learning but since I don’t really know exactly what I’m doing its hard. It is now going to the error page I created and nothing else. What am I doing wrong?
Firstly, you need to put a hash before the following lines of code:
(”ERROR - incorrect password for email address”);
(”ERROR - email address not found”);
One possible reason could be that the login details are not being returned from the database. Put the following code:
die(”Database Password: “.$myrow["fldPassword"]);
After the line:
$myrow = mysql_fetch_array($result);
This will print out the password and stop the script. If this is empty there is a problem pulling the records from the database. This is case sensitive.
Hello,
I am new to PHP and Mysql
I am trying to create a school site that will make it possible for students to check their results online. in this case, there would be a PIN given to the students that expires after 5 logins and cannot be used by more than a student. There would also be a serial number sort of to tally with each PIN code.
This has been the system here but i dont know if I can get a guide from this blog. If i can, help me get guide on the coding
Thank you so much!
Just wondering whats wrong with HT Access?
When I started off years ago I wrote a very complex secure log in system that I could use to control access to secure client areas, then after 2-3 years I discovered HT Access. I dont know why I didn’t use it before, I dont think I was familiar enough with it, but I cant think of anything that it cant work for, except very advanced login in systems.
.htaccess is certainly useful for creating logins, although you are very limited to what you can do with it. The advantage of using a database is that you can manage the list of users online with advanced features, such as, name, address, privileges and so forth.
Most applications require sessions to keep the user logged in and use the database of users to audit activity and manage access to content. Users can also have the ability to change their own details.
.htaccess certainly has a place for creating quick logins when the users are fixed and the application has no reliance on users.
thank you
do you have a session tracking page to add into each page to check if a user is logged in?
Yes, a session variable is the best way to keep a user logged in and also to ensure they have the privileges to view a page. Normally, you set the User ID as the session variable and check to see whether this is set on every page.
You can then use the session variable to get the users’ account details and then perform more advanced privilege checks (if required).
HTH,
Andy
How this can be secure? This is very poor and simple login.
1. Password in database is not encrypted.
2. You are not using encrypted connection.
3. Password before sending from client is not encrypted.
4. For security reason best for you is to check email and password in one SQL.
5. What happen if someone use proxy server?
6. What will be if some robot try to find password?
7. Nice will be if you can use in login form with same hidden filed with random parameter generated on server and stored on server.
This parameter is deferent every time when you visit login page.
In addition to vlado107 comment I would also recommend to use prepared statements for your sql queries. Even if you miss some checks on user’s input it makes your queries safe.
i accept this login technic.but one biggest problem.that is user will click forward or backward button so easily loginto other user site.so in doesnot make a secure.so please you will write coding about session based login technic.please i expect.