Sunday, January 10, 2010

how to validate user login

How to validate user login using MySQL with PHP and JavaScript?

Following example shows you how to validate user login in your web application.
Validate User Login with PHP,MySQL, and JavaScript
Suppose that you have a user login for your website or CMS. It is a best practice to validate user name and password before user press the login button. Because it prevents the additional request to your server. So it save your server resources. So you can check if the user has entered the user name and password before login. But keep in mind client side validation is not enough and you must do a server side validation for the login verification.In my example I used CSS for indicate errors. You can use JavaScript alert to ask to user to enter both user name and password before login. You can customize the login as your wish.

This is a complete example of user login validation. First of all you may need to know why to validate your login. Simply prevent unauthorized access to your account. Validation can do within several steps before send the request to the database server. Because hackers and several automated systems can send the large amount of request to the database server and make it busy or stuck the server. You can user JavaScript code to validate user name and password as client side validation. Also you can use a CAPTCHA verification code to determine the request actually comes from a human. As the 2nd step you can validate using a CAPTCHA code. So user must insert the text in the image correctly.

In this example I have used MySQLi library to database access. After user enter the CAPTCHA code correctly, you need to check the database for the entered user name as the 3rd step. So you have to design the database table for the user. In this table you have to store user_name, password, account creation time, last logged time,last logged IP address, number of login attempts. To build a more secure system you have to include above fields to your table. So you can check who is logged to the system and their IP address and logged time. They are very useful to determine unauthorized access to the system.

If user fails to enter his password correctly, you can assume that the login attempt from a hacker. So you can increase the number of logging attempts field by one. If the user fails 3 times to enter his password correctly, we can disable his user account temporally. Also in this step we can send a e-mail to the user regarding this login attempt. Then we can use other verification method such as SMS to reset the account. Even if the user successfully logged to the system, it is good idea to send a e-mail to the user including logged time and the IP address or country name. Every successful login, you have to reset the number of login attempt to the zero.

1. Validate user login using JavaScript as client side validation.

Copy and past bellow code as index.php. This is the file that use to login to the system.

Complete source code for validate user login
<?php
/*
Copyright by Duminda Chamara
http://kottawadumi.blogspot.com
*/
$message_id = (int)(isset($_REQUEST['message'])?(trim($_REQUEST['message'])!=''?$_REQUEST['message']:""):"");
if($message_id==1){
$message='User Name and password does not match';
}elseif($message_id==2){
$message='Your account has been disabled';
}else{
$message='&nbsp;';
}
?><!DOCTYPE HTML>
<html>
<head>
<title>Validate User Login</title>
<style type="text/css">
.login_form{border: 3px double #0080C0;background-color: #F8F8F8;border-radius: 5px 5px 5px 5px;font-family:Tahoma, Geneva, sans-serif;font-size:12px;padding:8px;margin-top:10%;background-image:url(../images/keys.png);background-repeat:no-repeat;background-position:right;width:270px;}
.login_form .title{font-size:14px;font-weight:bolder;margin-top:10px;}
.login_form input{border: 1px solid #0080C0;border-radius: 3px 3px 3px 3px;}
.login_form .error_input{border: 1px solid #FF0000;border-radius: 3px 3px 3px 3px;}
.login_form .message{color:#F00;}
</style>
<script type="text/javascript">
function validate_login(){
var user_name=document.getElementById("user_name");
var password=document.getElementById("password");
var error=0;
if(user_name.value.replace(/\s+$/,"")==""){
user_name.className='error_input';
error++;
}else{
user_name.className='';
}

if(password.value.replace(/\s+$/,"")==""){
password.className='error_input';
error++;
}else{
password.className='';
}

if(error>0){
document.getElementById("login_message").innerHTML="Please enter your login details";
return false;
}else{
return true;
}
}
</script>
</head>
<body>
<form id="userLogin" name="userLogin" action="login.php" method="post" onSubmit="javascript:return validate_login();">
<table border="0" align="center" cellpadding="2" cellspacing="0" class="login_form">
<tr>
<td colspan="3" class="title">Loign to the system</td>
</tr>
<tr>
<td align="right">User Name</td>
<td>:</td>
<td><input type="text" name="user_name" id="user_name" placeholder="User Name"></td>
</tr>
<tr>
<td align="right">Password</td>
<td>:</td>
<td><input type="password" name="password" id="password"></td>
</tr>
<tr>
<td align="right">&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" name="Login" id="Login" value="Login"></td>
</tr>
<tr>
<td align="right">&nbsp;</td>
<td>&nbsp;</td>
<td id="login_message" class="message">&nbsp;<?php echo $message;?></td>
</tr>
</table>
</form>
</body>
</html>

2. My SQL code for creating user table.

This is the MySQL database backup of the user table. Copy bellow SQL code in to your preferred SQL editor and execute it. Or you can create it manually.



SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `site_users`
-- ----------------------------
DROP TABLE IF EXISTS `site_users`;
CREATE TABLE `site_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
`last_logged_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_logon_ip` varchar(32) DEFAULT NULL,
`login_attempts` tinyint(4) DEFAULT NULL COMMENT '0',
`email_address` varchar(150) DEFAULT NULL,
`is_active` tinyint(4) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of site_users
-- ----------------------------
INSERT INTO `site_users` VALUES ('1', 'duminda', '202cb962ac59075b964b07152d234b70', null,

'127.0.0.1', '0', 'duminda@gmail.com', '1');
INSERT INTO `site_users` VALUES ('2', 'pami', '900150983cd24fb0d6963f7d28e17f72', null, null,

null, 'pamika@yahoo.com', '0');

3. PHP code for the validate user login with MySQL

Copy bellow code and save it as login.php file. Set your login form action to this file.



<?php
/*
Copyright by Duminda Chamara
http://kottawadumi.blogspot.com
*/

session_start();

$user_name = (isset($_POST['user_name'])?(trim($_POST['user_name'])!=''?$_POST['user_name']:""):"");
$password = (isset($_POST['password'])?(trim($_POST['password'])!=''?$_POST['password']:""):"");
$logged_ip = $_SERVER['REMOTE_ADDR'];

/*
If you are using CAPTCHA verification in your systems,
You can check the entered CAPTCHA code is correct or not.
if the CAPTCHA code is incorrect redirect to the login page.
*/

$mysqli = new mysqli("localhost", "root", "1234", "my_db");
if (mysqli_connect_errno()) { //Connection fail to the MySQL server
header("Location: index.php");
exit();
}else{
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT `id`,password,login_attempts FROM site_users WHERE user_name=? AND is_active=?")){
$active_users_only=1;

/* bind parameters for markers */
$stmt->bind_param("si",$user_name,$active_users_only);
$stmt->execute();/* execute query */

$stmt->bind_result($user_id,$md5_password,$login_attempts);/* bind result variables */
$stmt->store_result();
//$stmt->fetch();/* fetch value */

if($stmt->num_rows>0){/*There is a record associated with entered user name*/
$stmt->fetch();
//echo $user_name." ".$user_id." ".$login_attempts;
if($login_attempts>2){
//Disable the user login
//Hear we can assume that someone try to hack this user account.
//So we can send a e-mail to the user regarding this
//Here we can user step two verification such as send SMS to the user with verification code


$mysqli->close();/* close connection */
header("Location: index.php?message=2");
exit();
}else{
if(md5($password)===$md5_password){//password matched
/*
Create session is_logged and assign 1
You can use this session variable to checked if the
User has logged in your rest of pages.
*/

$_SESSION['is_logged']=1;

/* Password and user name matched Login successful
Even if the login successful, we can send a e-mail to the
User including login time and country details
*/


//reset login attempts to 0
$query="UPDATE site_users SET login_attempts=0,last_logon_ip='".$logged_ip."' WHERE `id`=".$user_id;
$mysqli->query($query);

$mysqli->close();
header("Location: user.php");
exit();

}else{//password does not matched
/*Here we need to increase the login attempts to prevent hacking
If user fail to authorized his login with 3 attempts,
User account can disable temporally.
*/

$query="UPDATE site_users SET login_attempts=login_attempts+1 WHERE `id`=".$user_id;
$mysqli->query($query);
header("Location: index.php?message=1");
exit();
}
}
}else{
$stmt->close();/* close statement */
$mysqli->close();/* close connection */
header("Location: index.php?message=1");
exit();
}
}else{
$stmt->close();
$mysqli->close();
header("Location: index.php");
exit();
}
}

?>

4. Redirect to login successful page.

After a successful login you can redirect the user to user account. Keep in mind you have to check the session variable is_logged=0 before proceeding any action. That means you have check the session at the beginning of each file. Hackers may be try hijack your session Cookie to login to your account using XSS attacks. So you can check the session with the IP address for more secure login. But if the IP address frequently change, it is not a good solution. copy and save following code as user.php

code for the user page.

<?
/*
Copyright by Duminda Chamara
http://kottawadumi.blogspot.com
*/
session_start();
$is_logged = (isset($_SESSION['is_logged'])?$_SESSION['is_logged']:0);

if($is_logged!=1){
header("Location: index.php");
exit();
}
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login Success</title>
</head>

<body>
<h1>You have Successfully Logged to the System</h1>
</body>
</html>

Download source code

4 comments:

Madan Ingnam said...

error is shown in return false statement. why?

The Slammer said...

This doesn't work at all!! You suck!!! Don't waste your time with this bullshit!

Duminda Chamara said...

Slammer did you try on this..?
This works fine. Please download the provided source code or create files in the article.

You have to enable php_mysqli extension to run this code.
Also need to enable php short tags (or you can replace them).

Please check it and let me know.

Guru said...

Thank you