Sie sind auf Seite 1von 61

Overview

In this tutorial, we create 3 php files for testing our code.


1. main_login.php
2. checklogin.php
3. login_success.php
Steps
1. Create table "members" in database "test".
2. Create file main_login.php.
3. Create file checklogin.php.
4. Create file login_success.php.
5. Create file logout.php
If you don't know how to create database, click here

STEP1: Create table "members"


For testing this code, we need to create database "test" and create table "members".

CREATE TABLE `members` (


`id` int(4) NOT NULL auto_increment,
`username` varchar(65) NOT NULL default '',
`password` varchar(65) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;
--- Dumping data for table `members`
-INSERT INTO `members` VALUES (1, 'john', '1234');

STEP2: Create file main_login.php

The first file we need to create is "main_login.php" which is a login form.

############### Code
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1"
bgcolor="#CCCCCC">
<tr>
<form name="form1" method="post" action="checklogin.php">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td colspan="3"><strong>Member Login </strong></td>
</tr>
<tr>
<td width="78">Username</td>
<td width="6">:</td>
<td width="294"><input name="myusername" type="text" id="myusername"></td>
</tr>
<tr>
<td>Password</td>
<td>:</td>
<td><input name="mypassword" type="text" id="mypassword"></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="Login"></td>
</tr>
</table>
</td>
</form>
</tr>
</table>

STEP3: Create file checklogin.php

We have a login form in step 2, when a user submit their username and password, PHP code in
checklogin.php will check that this user exist in our database or not.

If user has the right username and password, then the code will register username and password
in the session and redirect to "login_success.php". If username or password is wrong the system
will show "Wrong Username or Password".

############### Code
<?php
$host="localhost"; // Host name
$username=""; // Mysql username
$password=""; // Mysql password
$db_name="test"; // Database name
$tbl_name="members"; // Table name
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
// username and password sent from form
$myusername=$_POST['myusername'];
$mypassword=$_POST['mypassword'];
// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);
$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and
password='$mypassword'";
$result=mysql_query($sql);
// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1){

// Register $myusername, $mypassword and redirect to file "login_success.php"


session_register("myusername");
session_register("mypassword");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}
?>

STEP4: Create file login_success.php


User can't view this page if the session is not registered.

############### Code

// Check if session is not registered, redirect back to main page.


// Put this code in first line of web page.
<?php
session_start();
if(!session_is_registered(myusername)){
header("location:main_login.php");
}
?>
<html>
<body>
Login Successful
</body>
</html>

STEP5: Create file Logout.php


If you want to logout, create this file. The code in this file will destroy the session.
// Put this code in first line of web page.
<?php
session_start();
session_destroy();
?>

For PHP5 User - checklogin.php

############### Code
<?php
ob_start();
$host="localhost"; // Host name
$username=""; // Mysql username
$password=""; // Mysql password
$db_name="test"; // Database name
$tbl_name="members"; // Table name
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
// Define $myusername and $mypassword
$myusername=$_POST['myusername'];
$mypassword=$_POST['mypassword'];
// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);
$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and
password='$mypassword'";
$result=mysql_query($sql);
// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1){
// Register $myusername, $mypassword and redirect to file "login_success.php"
session_register("myusername");
session_register("mypassword");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}

ob_end_flush();
?>

Encrypting Password - Make your Login More Secure

First of all create a database and table as below.


you can create it by importing following sql command in to your phpmyadmin.
database : dbtest
table : users
CREATE DATABASE `dbtest` ;
CREATE TABLE `dbtest`.`users` (
`user_id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 25 ) NOT NULL ,
`email` VARCHAR( 35 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL ,
UNIQUE (`email`)
) ENGINE = MYISAM ;

copy-paste the above sql code into phpmyqdmin to create database and table.
Now we have to create following files..
dbconnect.php

register.php
index.php
home.php
logout.php

dbconnect.php
contains code for localhost connection and database selection.
<?php
if(!mysql_connect("localhost","root",""))
{
die('oops connection problem ! --> '.mysql_error());
}
if(!mysql_select_db("dbtest"))
{
die('oops database selection problem ! --> '.mysql_error());
}
?>

NOTE : we should have start session in all the pages.


>> I have used here simple HTML5 required attribute to validate the following register and login
forms.
if you want to know more about validations click here : validations

register.php
contains simple html form and few lines of php code.
save this file as register.php, this file contains simple html form with all the required
registration fields except user id because its auto incremented and some php code for registering
a new user. all the user registration process can be done in this single php file.
<?php
session_start();
if(isset($_SESSION['user'])!="")
{
header("Location: home.php");
}
include_once 'dbconnect.php';
if(isset($_POST['btn-signup']))
{
$uname = mysql_real_escape_string($_POST['uname']);
$email = mysql_real_escape_string($_POST['email']);
$upass = md5(mysql_real_escape_string($_POST['pass']));
if(mysql_query("INSERT INTO users(username,email,password)
VALUES('$uname','$email','$upass')"))
{
?>
<script>alert('successfully registered ');</script>
<?php
}

else
{
?>

<script>alert('error while registering you...');</script>


<?php

}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login & Registration System</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<center>
<div id="login-form">
<form method="post">
<table align="center" width="30%" border="0">
<tr>
<td><input type="text" name="uname" placeholder="User Name" required /></td>
</tr>
<tr>
<td><input type="email" name="email" placeholder="Your Email" required /></td>
</tr>
<tr>
<td><input type="password" name="pass" placeholder="Your Password" required
/></td>
</tr>
<tr>
<td><button type="submit" name="btn-signup">Sign Me Up</button></td>
</tr>
<tr>
<td><a href="index.php">Sign In Here</a></td>
</tr>
</table>
</form>
</div>
</center>
</body>
</html>

Now, after creating registration page successfully then move ahead to create login page.
ive written this login script with little bit security to prevent your website from sql injection.

index.php/login page
this file also contains html form with two input box which will take user email and user
password entered by user and then after submitting the form, the php code will match that user

email and password combination in database and when it finds both results in table then it will
start a session and allow user to access home page else it will show appropriate message.
<?php
session_start();
include_once 'dbconnect.php';
if(isset($_SESSION['user'])!="")
{
header("Location: home.php");
}
if(isset($_POST['btn-login']))
{
$email = mysql_real_escape_string($_POST['email']);
$upass = mysql_real_escape_string($_POST['pass']);
$res=mysql_query("SELECT * FROM users WHERE email='$email'");
$row=mysql_fetch_array($res);
if($row['password']==md5($upass))
{
$_SESSION['user'] = $row['user_id'];
header("Location: home.php");
}
else
{
?>
<script>alert('wrong details');</script>
<?php
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>cleartuts - Login & Registration System</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<center>
<div id="login-form">
<form method="post">
<table align="center" width="30%" border="0">
<tr>
<td><input type="text" name="email" placeholder="Your Email" required /></td>
</tr>
<tr>
<td><input type="password" name="pass" placeholder="Your Password" required
/></td>
</tr>
<tr>
<td><button type="submit" name="btn-login">Sign In</button></td>
</tr>
<tr>
<td><a href="register.php">Sign Up Here</a></td>
</tr>

</table>
</form>
</div>
</center>
</body>
</html>

after registration page and login page we need to create home page which shows users
dashboard, which is authentic page and this page cannot access without logging in.

home.php
this page shows welcome message of logged in user with username and a hyper link to logout the
user and redirects the logout.php page.
<?php
session_start();
include_once 'dbconnect.php';
if(!isset($_SESSION['user']))
{
header("Location: index.php");
}
$res=mysql_query("SELECT * FROM users WHERE user_id=".$_SESSION['user']);
$userRow=mysql_fetch_array($res);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome - <?php echo $userRow['email']; ?></title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div id="header">
<div id="left">
<label>cleartuts</label>
</div>
<div id="right">
<div id="content">
hi' <?php echo $userRow['username']; ?>&nbsp;<a href="logout.php?
logout">Sign Out</a>
</div>
</div>
</div>
</body>
</html>

logout.php

this page contains only few lines of php code to unset and destroy the current logged in users
session, and after destroying the session the page automatically redirect to the index/login page.
<?php
session_start();
if(!isset($_SESSION['user']))
{
header("Location: index.php");
}
else if(isset($_SESSION['user'])!="")
{
header("Location: home.php");
}
if(isset($_GET['logout']))
{
session_destroy();
unset($_SESSION['user']);
header("Location: index.php");
}
?>

style.css
style.css file which makes beautify all the pages.
@charset "utf-8";
/* CSS Document */
*
{
margin:0;
padding:0;
}
#login-form
{
margin-top:70px;
}
table
{
border:solid #dcdcdc 1px;
padding:25px;
box-shadow: 0px 0px 1px rgba(0,0,0,0.2);
}
table tr,td
{
padding:15px;
//border:solid #e1e1e1 1px;
}
table tr td input
{
width:97%;
height:45px;
border:solid #e1e1e1 1px;
border-radius:3px;

padding-left:10px;
font-family:Verdana, Geneva, sans-serif;
font-size:16px;
background:#f9f9f9;
transition-duration:0.5s;
box-shadow: inset 0px 0px 1px rgba(0,0,0,0.4);
}
table tr td button
{
width:100%;
height:45px;
border:0px;
background:rgba(12,45,78,11);
background:-moz-linear-gradient(top, #595959 , #515151);
border-radius:3px;
box-shadow: 1px 1px 1px rgba(1,0,0,0.2);
color:#f9f9f9;
font-family:Verdana, Geneva, sans-serif;
font-size:18px;
font-weight:bolder;
text-transform:uppercase;
}
table tr td button:active
{
position:relative;
top:1px;
}
table tr td a
{
text-decoration:none;
color:#00a2d1;
font-family:Verdana, Geneva, sans-serif;
font-size:18px;
}
/* css for home page

*/

*
{
margin:0;
padding:0;
}
#header
{
width:100%;
height:60px;
background:rgba(00,11,22,33);
color:#9fa8b0;
font-family:Verdana, Geneva, sans-serif;
}
#header #left
{
float:left;
position:relative;
}
#header #left label

position:relative;
top:5px;
left:100px;
font-size:35px;

}
#header #right
{
float:right;
position:relative;
}
#header #right #content
{
position:relative;
top:20px;
right:100px;
color:#fff;
}
#header #right #content a
{
color:#00a2d1;
}
/* css for home page */

How to Create a Secure Login Script in PHP and MySQL


Eight Parts:Configure Your ServerConfigure the MySQL DatabaseCreate Database Connection
PageCreate the PHP FunctionsCreate Processing PagesCreate Javascript FilesCreate HTML
PagesProtecting Pages
With more and more stories of cracking in the news, developers are looking for the best ways of
securing their sites. If your site has a member system, it could be at risk from being cracked and
your users' data could be compromised. This guide will show you one attempt at making a secure
login using PHP. The code is as good as we can make it, but security and especially encryption
are complex subjects that are changing all the time, and we can't claim to have the entire field
mastered. Therefore we may have missed a few tricks in our code. If we have, please let us know
and we'll try to incorporate any improvements into what we have.
Writing a login system is a complex topic and not something to be undertaken by those who are
not intimately familiar with a wide variety of security topics. The login system presented here is
to be used for educational purposes, not a production environment. If you need a login system for
a production environment, please locate a prepacked and vetted system. There are several listed
in the Warnings section at the end of this article.
Following this guide will help guard against many types of attack that crackers can use to gain
control of other users' accounts, delete accounts and/or change data. Below is a list of possible
attacks this guide tries to defend against:

SQL Injections

Session Hijacking

Network Eavesdropping

Cross Site Scripting

Brute Force Attacks

The approach is to use a mixture of data filtering, encryption and other methods to make the lives
of the bad guys just that little bit more difficult.
We're continually trying to improve this script. The very latest version of the code is available
from github. There may be some differences between the code you download in this way from
the code quoted in this article. You should also know that we have made no attempt to make the
HTML pages output by the application look at all pretty.
You may also notice that we do not close PHP tags in files containing only PHP code. This is in
line with most code formatting recommendations.
Finally, you need to know that we ask you to create all the application's non-HTML files in
various directories within the application's root directory. The easiest way to get the correct
directory structure is to download the latest code by following one of the links above.
Please feel free to use this application as a basis for your own implementation, but don't use it as
any kind of example of good coding practice!

Things You'll Need


As we will be using the mysqli_* set of PHP classes to access our MySQL database you will
need the following versions of PHP and mySQL.

PHP version 5.3 or later

MySQL version 4.1.3 or later

You will also need, of course, a web server configured to use PHP, to host your pages. This will
most likely be your Web Host's web server, unless you are hosting the site yourself.
To check the version of PHP and MySQL on your server use the phpinfo(); function.
Part 1 of 8: Configure Your Server
1. 1
Install a Web Server, PHP and MySQL on your server.
Most web hosting services will have PHP and MySQL already installed. You will
just have to check they have the most recent versions of PHP and MySQL for
this guide to work. If they don't have at least PHP5.3 and MySQL5 you might
like to ask a few questions about their commitment to security. Keeping your
software up-to-date is a part of the security process.
If you have your own server or computer, you should install the required
software in the normal way for your system. Generally speaking, if you are
not going to use the setup for production purposes and you are developing
under Windows or OS/X, installing an XAMPP stack is the way to go. Get the
appropriate version for your operating system at:
http://www.apachefriends.org/en/xampp.html
But please note that you should under no circumstances use XAMPP to create
a production server environment for you.
Under Linux, use your package manager to download and install the
necessary packages. Some distributions, like Ubuntu, package all the
necessary applications into one bundle. Just do the following from a terminal
window in Ubuntu:

sudo apt-get install lamp-server^ phpmyadmin

However you install the necessary elements, please ensure you configure
MySQL with a secure root password.

Ad
Ad
Part 2 of 8: Configure the MySQL Database
1. 1
Create a MySQL database.
Log into your database as an administrative user (usually root)
In this guide we will create a database called "secure_login".
See how to Create-a-Database-in-Phpmyadmin.
You can either use the code below or do the same thing in phpMyAdmin/your
favourite GUI MySQL client, if you prefer:
CREATE DATABASE `secure_login`;

Note: Some hosting services don't allow you to create a database through
phpMyAdmin, Learn how to do it in cPanel.
2. 2
Create a user with only SELECT, UPDATE and INSERT privileges.
Creating a user with restricted privileges means that if there was ever a
breach of security in our script the hacker couldn't delete or drop anything
from our database. Using these privileges, you can get by doing pretty much
anything you would want to in your application. If you are really paranoid,
create a user for each function.
Of course you will need to be logged into MySQL as a user with sufficient
privileges in order to create a user. This user will usually be root.
These are the details of the user we created:
o

User: "sec_user"

Password: "eKcGZr59zAa2BEWU"

Note: it is a good idea to change the password from the one given above when running on
your own server. Make sure, if you do this, that you also change the code below, and your
PHP database connection code in the application we are creating.
Remember it doesn't need to be a password that you can remember so make it as
complicated as possible. Here's a random password generator
Given below is the SQL code for creating the database user and granting it the necessary
permissions. Or you can do this in a GUI database client like phpmyadmin if you prefer:
CREATE USER 'sec_user'@'localhost' IDENTIFIED BY 'eKcGZr59zAa2BEWU';
GRANT SELECT, INSERT, UPDATE ON `secure_login`.* TO 'sec_user'@'localhost';

If you see yourself deleting records from either of the tables in this module,
you may want to add DELETE to the list of privileges, or you may prefer to
create a different user with just the DELETE privilege, and only on the table
from which you want to delete records if you don't want to delete from both.
You do not need to grant DELETE privileges at all for anything in this example
script.
3. 3
Create a MySQL table named "members".

The code below creates a table with five fields (id, username, email, password, salt). We
use the CHAR datatype for fields we know the length of, as the fields "password" and
"salt" will always be 128 characters long. Using CHAR here saves on processing power:
CREATE TABLE `secure_login`.`members` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(30) NOT NULL,
`email` VARCHAR(50) NOT NULL,
`password` CHAR(128) NOT NULL,
`salt` CHAR(128) NOT NULL
) ENGINE = InnoDB;

As we've said before, you can do this in whatever type of client you prefer.
4. 4
Create a table to store login attempts.
We will use this table to store login attempts for a user. This is one way in
which we will make brute force attacks more difficult:

CREATE TABLE `secure_login`.`login_attempts` (


`user_id` INT(11) NOT NULL,
`time` VARCHAR(30) NOT NULL
) ENGINE=InnoDB

5. 5
Create a test row in table "members".
It will be important to be able to test your login script, so below is the script
to create a user with known details:
o

Username: test_user

Email: test@example.com

Password: 6ZaxN2Vzm9NUJT2y

The code you need in order to be able to log in as this user is:
INSERT INTO `secure_login`.`members` VALUES(1, 'test_user', 'test@example.com',
'00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac45529e0726559645a
caed6f3ae58a286b9f075916ebf66cacc',
'f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a8695077dcf81932aa
59006423976224be0390395bae152d4ef');

Ad
Part 3 of 8: Create Database Connection Page
1. 1
Create a global configurations page
Create a folder called "includes" in the root directory of the
application and then create a new PHP file in that directory. Call it pslconfig.php. In a production environment you'll probably want to locate this
file and all your other include files, outside of the web server's document
root. If you do that, and we strongly suggest that you do, you will need to
alter your include or require statements as necessary, so that the application
can find the include files.
Locating your include files outside of the web server's document root means
that your file cannot be located using a URL. So, if someone mistakenly
dropped the 'php' extension, say, or messed up the file permissions the file
still could not be displayed as text in a browser window.

The file contains global configuration variables. Things like whether anyone
can register, whether or not it's a secure (HTTPS) connection, and other stuff
as well as the database details could also go here...
<?php
/**
* These are the database login details
*/
define("HOST", "localhost");
// The host you want to connect to.
define("USER", "sec_user");
// The database username.
define("PASSWORD", "eKcGZr59zAa2BEWU");
// The database password.
define("DATABASE", "secure_login");
// The database name.
define("CAN_REGISTER", "any");
define("DEFAULT_ROLE", "member");
define("SECURE", FALSE);
?>

// FOR DEVELOPMENT ONLY!!!!

2. 2
Create the database connection page
This is the PHP code that we will use to connect to our mySQL
database. Create a new PHP file called db_connect.php in the application's
includes directory and add the code below. You can then include the file onto
any page you wish to connect to the database.
<?php
include_once 'psl-config.php';
// As functions.php is not included
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);

Ad
Part 4 of 8: Create the PHP Functions

These functions will do all the processing of the login script. Add all of the functions to a page
called functions.php in the includes directory of the application.
1. 1
Securely start a PHP session.
PHP sessions are known not to be secure, therefore it is important not just to
put "session_start();" at the top of every page on which you want to use PHP
sessions. We are going to create a function called "sec_session_start()", this
will start a PHP session in a secure way. You should call this function at the
top of any page in which you wish to access a PHP session variable. If you are
really concerned about security and the privacy of your cookies, have a look
at this article: Create-a-Secure-Session-Managment-System-in-Php-and-Mysql.
This function makes your login script a whole lot more secure. It stops

crackers accessing the session id cookie through JavaScript (for example in


an XSS attack). Also the "session_regenerate_id()" function, which
regenerates the session id on every page reload, helps prevent session
hijacking. Note: If you are using HTTPS in your login application set the
"$secure" variable to true. In a production environment it is essential that you
use HTTPS.
Create a new file called functions.php in your application's includes directory
and add the following code to it:
<?php
include_once 'psl-config.php';
function sec_session_start() {
$session_name = 'sec_session_id';
// Set a custom session name
$secure = SECURE;
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start();
// Start the PHP session
session_regenerate_id(true);
// regenerated the session, delete the old one.
}

2. 2
Create the Login Function.
This function will check the email and password against the database. It will
return true if there is a match. Add this function to your functions.php file:
function login($email, $password, $mysqli) {
// Using prepared statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
FROM members
WHERE email = ?
LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute();
// Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $salt);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts
if (checkbrute($user_id, $mysqli) == true) {

// Account is locked
// Send an email to user saying their account is locked
return false;
} else {
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now')");
return false;
}
}
} else {
// No user exists.
return false;
}
}
}

3. 3
The Brute Force Function.
Brute force attacks are when a hacker tries thousands of different passwords
on an account, either randomly generated passwords or from a dictionary. In
our script if a user account has more than five failed logins their account is
locked.
Brute force attacks are hard to prevent. A few ways we can prevent them are
using a CAPTCHA test, locking user accounts and adding a delay on failed
logins, so the user cannot login for another thirty seconds.
We strongly recommend using a CAPTCHA. As yet we have not implemented
this functionality in the example code, but hope to do so in the near future,
using SecureImage, since it does not require registration. You may prefer
something better known such as reCAPTCHA from Google.
Whichever system you decide on, we suggest you only display the CAPTCHA
image after two failed login attempts so as to avoid inconveniencing the user
unnecessarily.

When faced with the problem of brute force attacks, most developers simply
block the IP address after a certain amount of failed logins. But there are
many tools to automate the process of making attacks like these; and these
tools can go through a series of proxies and even change the IP on each
request. Blocking all these IP addresses could mean you're blocking
legitimate users as well. In our code we'll log failed attempts and lock the
user's account after five failed login attempts. This should trigger the sending
of an email to the user with a reset link, but we have not implemented this in
our code. Here is the code for the checkbrute() function at the time of writing.
Add it to your functions.php code:
function checkbrute($user_id, $mysqli) {
// Get timestamp of current time
$now = time();
// All login attempts are counted from the past 2 hours.
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $mysqli->prepare("SELECT time
FROM login_attempts
WHERE user_id = ?
AND time > '$valid_attempts'")) {
$stmt->bind_param('i', $user_id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there have been more than 5 failed logins
if ($stmt->num_rows > 5) {
return true;
} else {
return false;
}
}
}

4. 4
Check logged in status.
We do this by checking the "user_id" and the "login_string" SESSION
variables. The "login_string" SESSION variable has the user's browser
information hashed together with the password. We use the browser
information because it is very unlikely that the user will change their browser
mid-session. Doing this helps prevent session hijacking. Add this function to
your functions.php file in the includes folder of your application:
function login_check($mysqli) {
// Check if all session variables are set
if (isset($_SESSION['user_id'],
$_SESSION['username'],
$_SESSION['login_string'])) {
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];

// Get the user-agent string of the user.


$user_browser = $_SERVER['HTTP_USER_AGENT'];
if ($stmt = $mysqli->prepare("SELECT password
FROM members
WHERE id = ? LIMIT 1")) {
// Bind "$user_id" to parameter.
$stmt->bind_param('i', $user_id);
$stmt->execute();
// Execute the prepared query.
$stmt->store_result();
if ($stmt->num_rows == 1) {
// If the user exists get variables from result.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password . $user_browser);
if ($login_check == $login_string) {
// Logged In!!!!
return true;
} else {
// Not logged in
return false;
}
} else {
// Not logged in
return false;
}
} else {
// Not logged in
return false;
}
} else {
// Not logged in
return false;
}
}

5. 5
Sanitize URL from PHP_SELF
This next function sanitizes the output from the PHP_SELF server
variable. It is a modificaton of a function of the same name used by the
WordPress Content Management System:
function esc_url($url) {
if ('' == $url) {
return $url;
}
$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
$strip = array('%0d', '%0a', '%0D', '%0A');
$url = (string) $url;
$count = 1;
while ($count) {
$url = str_replace($strip, '', $url, $count);
}
$url = str_replace(';//', '://', $url);
$url = htmlentities($url);
$url = str_replace('&amp;', '&#038;', $url);
$url = str_replace("'", '&#039;', $url);

if ($url[0] !== '/') {


// We're only interested in relative links from $_SERVER['PHP_SELF']
return '';
} else {
return $url;
}
}

The trouble with using the server variable unfiltered is that it can be used in a
cross site scripting attack. Most references will simply tell you to filter it using
htmlentities(), however even this appears not to be sufficient hence the belt
and braces approach in this function.
Others suggest leaving the action attribute of the form blank, or set to a null
string. Doing this, though, leaves the form open to an iframe clickjacking
attack.
Ad
Part 5 of 8: Create Processing Pages
1. 1
Create the login processing page (process_login.php)
Create a file to process logins, called process_login.php in the
application's includes directory. It goes in this directory because it
contains no HTML markup.
We will use the mysqli_* set of PHP functions as this is one of the most up-todate mySQL extensions.
<?php
include_once 'db_connect.php';
include_once 'functions.php';
sec_session_start(); // Our custom secure way of starting a PHP session.
if (isset($_POST['email'], $_POST['p'])) {
$email = $_POST['email'];
$password = $_POST['p']; // The hashed password.
if (login($email, $password, $mysqli) == true) {
// Login success
header('Location: ../protected_page.php');
} else {
// Login failed
header('Location: ../index.php?error=1');
}
} else {
// The correct POST variables were not sent to this page.
echo 'Invalid Request';
}

2. 2
Create a logout script.
Your logout script must start the session, destroy it and then redirect to
somewhere else. Note: it might be a good idea to add CSRF protection here in
case someone sends a link hidden in this page somehow. For more
information about CSRF you could visit Coding Horror.
The current code for logging out the user, which you should add to a file
called logout.php in the application's includes directory, is:
<?php
include_once 'functions.php';
sec_session_start();
// Unset all session values
$_SESSION = array();
// get session parameters
$params = session_get_cookie_params();
// Delete the actual cookie.
setcookie(session_name(),
'', time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]);
// Destroy session
session_destroy();
header('Location: ../index.php');

3. 3
Registration Page.
The registration code is included in two new files, called register.php in the
application's root directory and register.inc.php in the includes directory. It
does the following things:
o

Obtains and validates the username the user wishes to adopt

Obtains and validates the user's email address

Obtains and validates the password the user wants to use

Hashes the password and passes it back to the register.php page (i.e. it
posts to itself)

Most of the validation is done in JavaScript, client side. This is because the

user has no motivation to circumvent these checks. Why would a user want
to create an account that would be less secure than otherwise? We will
discuss the JavaScript in the next section.
For now, just create the register.php file and include the following code in it:
<?php
include_once 'includes/register.inc.php';
include_once 'includes/functions.php';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Registration Form</title>
<script type="text/JavaScript" src="js/sha512.js"></script>
<script type="text/JavaScript" src="js/forms.js"></script>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<!-- Registration form to be output if the POST variables are not
set or if the registration script caused an error. -->
<h1>Register with us</h1>
<?php
if (!empty($error_msg)) {
echo $error_msg;
}
?>
<ul>
<li>Usernames may contain only digits, upper and lower case letters and
underscores</li>
<li>Emails must have a valid email format</li>
<li>Passwords must be at least 6 characters long</li>
<li>Passwords must contain
<ul>
<li>At least one uppercase letter (A..Z)</li>
<li>At least one lower case letter (a..z)</li>
<li>At least one number (0..9)</li>
</ul>
</li>
<li>Your password and confirmation must match exactly</li>
</ul>
<form action="<?php echo esc_url($_SERVER['PHP_SELF']); ?>"
method="post"
name="registration_form">
Username: <input type='text'
name='username'
id='username' /><br>
Email: <input type="text" name="email" id="email" /><br>
Password: <input type="password"
name="password"
id="password"/><br>
Confirm password: <input type="password"
name="confirmpwd"
id="confirmpwd" /><br>
<input type="button"
value="Register"
onclick="return regformhash(this.form,
this.form.username,
this.form.email,
this.form.password,
this.form.confirmpwd);" />
</form>
<p>Return to the <a href="index.php">login page</a>.</p>
</body>
</html>

The register.inc.php file in the includes directory should contain the following
code:
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already
exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}

//
//
//
//

TODO:
We'll also have to account for the situation where the user doesn't have
rights to do registration, by checking what type of user is attempting to
perform the operation.

if (empty($error_msg)) {
// Create a random salt
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); // Did
not work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password,
salt) VALUES (?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: ./register_success.php');
}
}

If there is no POST data passed into the form, the registration form is displayed. The
form's submit button calls the JavaScript function regformhash(). This function does the
necessary validation checks and submits the form when all is well. The JavaScript
functions are discussed in the next section.
If the POST data exists, some server side checks are done to sanitise and validate it.
NOTE that these checks are not complete at the time of writing. Some of the issues are
mentioned in the comments in the file. At present, we just check that the email address is
in the correct format, that the hashed password is the correct length and that the user is
not trying to register an email that has already been registered.
If everything checks out, the new user is registered by writing a new record into the
members table.
Ad
Part 6 of 8: Create Javascript Files
1. 1
Create sha512.js file
This file is an implementation in JavaScript of the hashing algorithm
sha512. We will use the hashing function so our passwords don't get sent in

plain text.
The file can be downloaded from pajhome.org.uk
(It is also saved in the github repository)
Store your copy of this file in a directory called "js", off the root directory of
the application.
2. 2
Create forms.js file
This file, which you should create in the js directory of the
application, will handle the hashing of the passwords for the login
(formhash()) and registration (regformhash()) forms:
function formhash(form, password) {
// Create a new element input, this will be our hashed password field.
var p = document.createElement("input");
// Add the new element to our form.
form.appendChild(p);
p.name = "p";
p.type = "hidden";
p.value = hex_sha512(password.value);
// Make sure the plaintext password doesn't get sent.
password.value = "";
// Finally submit the form.
form.submit();
}
function regformhash(form, uid, email, password, conf) {
// Check each field has a value
if (uid.value == ''
||
email.value == ''
||
password.value == '' ||
conf.value == '') {
alert('You must provide all the requested details. Please try again');
return false;
}
// Check the username
re = /^\w+$/;
if(!re.test(form.username.value)) {
alert("Username must contain only letters, numbers and underscores. Please try again");
form.username.focus();
return false;
}
//
//
//
if

Check that the password is sufficiently long (min 6 chars)


The check is duplicated below, but this is included to give more
specific guidance to the user
(password.value.length < 6) {
alert('Passwords must be at least 6 characters long. Please try again');
form.password.focus();
return false;

// At least one number, one lowercase and one uppercase letter


// At least six characters
var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/;
if (!re.test(password.value)) {
alert('Passwords must contain at least one number, one lowercase and one uppercase
letter. Please try again');
return false;
}
// Check password and confirmation are the same
if (password.value != conf.value) {
alert('Your password and confirmation do not match. Please try again');
form.password.focus();
return false;
}
// Create a new element input, this will be our hashed password field.
var p = document.createElement("input");
// Add the new element to our form.
form.appendChild(p);
p.name = "p";
p.type = "hidden";
p.value = hex_sha512(password.value);
// Make sure the plaintext password doesn't get sent.
password.value = "";
conf.value = "";
// Finally submit the form.
form.submit();
return true;
}

In both cases, the JavaScript hashes the password and passes it in the POST data by
creating and populating a hidden field.
Ad
Part 7 of 8: Create HTML Pages
1. 1
Create the login form (index.php).
This is an HTML form with two text fields, named "email" and "password". The
form's submit button calls the JavaScript function formhash(), which will
generate a hash of the password, and send "email" and "p" (the hashed
password) to the server. You should create this file in the application's root
directory.
When logging in, it is best to use something that is not public, for this guide
we are using the email as the login id, the username can then be used to
identify the user. If the email is not displayed on any pages within the wider

application, it adds another unknown for anyone trying to crack the account.
Note: even though we have encrypted the password so it is not sent in plain
text, it is essential that you use the HTTPS protocol (TLS/SSL) when sending
passwords in a production system. It cannot be stressed enough that simply
hashing the password is not enough. A man-in-the-middle attack could be
mounted to read the hash being sent and use it to log in.
<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
if (login_check($mysqli) == true) {
$logged = 'in';
} else {
$logged = 'out';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Secure Login: Log In</title>
<link rel="stylesheet" href="styles/main.css" />
<script type="text/JavaScript" src="js/sha512.js"></script>
<script type="text/JavaScript" src="js/forms.js"></script>
</head>
<body>
<?php
if (isset($_GET['error'])) {
echo '<p class="error">Error Logging In!</p>';
}
?>
<form action="includes/process_login.php" method="post" name="login_form">
Email: <input type="text" name="email" />
Password: <input type="password"
name="password"
id="password"/>
<input type="button"
value="Login"
onclick="formhash(this.form, this.form.password);" />
</form>
<?php
if (login_check($mysqli) == true) {
echo '<p>Currently logged ' . $logged . ' as ' .
htmlentities($_SESSION['username']) . '.</p>';
echo '<p>Do you want to change user? <a href="includes/logout.php">Log
out</a>.</p>';
} else {
echo '<p>Currently logged ' . $logged . '.</p>';
echo "<p>If you don't have a login, please <a
href='register.php'>register</a></p>";
}
?>
</body>
</html>

2. 2

Create the register_success.php page


Create a new PHP web page called register_success.php, in the root
directory of the application. This is the page to which the user is
redirected after successfully registering. Of course you can make this page
anything you like or redirect to another page entirely (or even not at all). It's
up to you. The page should be located in the root directory of the application.
The current register_success.php page that we have written looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Registration Success</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<h1>Registration successful!</h1>
<p>You can now go back to the <a href="index.php">login page</a> and log in</p>
</body>
</html>

3. 3
Create the error page
Create a new HTML page in the root directory of the application. Call
it error.php This is the page to which users will be directed if an error occurs
during the login or registration process, or when trying to establish a secure
session. The code given below simply provides a bare bones error page. You
will probably need something a bit more sophisticated. However, please note
that the input into the page must be properly filtered to guard against XSS
attacks. The example page code is:
<?php
$error = filter_input(INPUT_GET, 'err', $filter = FILTER_SANITIZE_STRING);
if (! $error) {
$error = 'Oops! An unknown error happened.';
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Error</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<h1>There was a problem</h1>
<p class="error"><?php echo $error; ?></p>
</body>
</html>

Ad
Part 8 of 8: Protecting Pages
1. 1
Page Protection Script.
One of the most common problems with authentication systems is the
developer forgetting to check if the user is logged in. It is very important you
use the code below on every protected page to check that the user is logged
in. Make sure you use this function to check if the user is logged in.
// Include database connection and functions here. See 3.1.
sec_session_start();
if(login_check($mysqli) == true) {
// Add your protected page content here!
} else {
echo 'You are not authorized to access this page, please login.';
}

As an example of what you should do, we have included a sample protected page. Create
a file called protected_page.php in the root directory of the application. The file should
contain something like the following:
<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Secure Login: Protected Page</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<?php if (login_check($mysqli) == true) : ?>
<p>Welcome <?php echo htmlentities($_SESSION['username']); ?>!</p>
<p>
This is an example protected page. To access this page, users
must be logged in. At some stage, we'll also check the role of
the user, so pages will be able to determine the type of user
authorised to access the page.
</p>
<p>Return to <a href="index.php">login page</a></p>
<?php else : ?>
<p>
<span class="error">You are not authorized to access this page.</span> Please <a
href="index.php">login</a>.
</p>
<?php endif; ?>
</body>
</html>

Our application redirects to this page after a successful login. Your own implementation
does not have to do this, of course.

his lesson is part of an ongoing User Authentication tutorial. The first part is here: User
Authentication along with all the files you need.

The first script to take a look at in your login folder is login.php. Open up this script in a text
editor, and well see how it works. Of course, you can fire up your server and try it out. What
you'll see is a simple login page with textboxes for username and password, as well as a submit
button. It will look like this:

The HTML for this form can be seen at the bottom of the login.php script that you have
(hopefully) by now opened. There's nothing special about it. But notice that there's a PHP print
statement in the HTML Body section:
<?PHP print $errorMessage;?>
This is for displaying error messages for the user.
The first few line of the script, though, just set up some variables:
$uname = "";
$pword = "";
$errorMessage = "";
$num_rows = 0;

The $errorMessage variable is an important one. We'll add something to this variable, if an error
occurs. We'll then check to see if it's blank or not.
The next part of the code is just the SQL checking function you met earlier. This aims to prevent
SQL injection attacks. After this code, we check to see if the form has been POSTED or not (was
the Submit button clicked):
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
Most of our code goes between the curly brackets of this if statement. The first thing to do is to
get the username and password from the textboxes:
$uname = $_POST['username'];
$pword = $_POST['password'];
We then deal with any unwanted HTML (scripting attacks):
$uname = htmlspecialchars($uname);
$pword = htmlspecialchars($pword);
Next, we attempt to connect to the database:
$user_name = "root";
$pass_word = "";
$database = "login";
$server = "127.0.0.1";
$db_handle = mysql_connect($server, $user_name, $pass_word);
$db_found = mysql_select_db($database, $db_handle);
If the database was found, then the variable called $db_found will be true. We check for this in
the next lines:
if ($db_found) {
}
else {
$errorMessage = "Error logging on";
}

If the database isn't found, then some text is added to the error message variable. If the database
was found, strip the incoming text of any unwanted characters (SQL Injection attacks). These
next two lines call the function at the top of the code:
$uname = quote_smart($uname, $db_handle);
$pword = quote_smart($pword, $db_handle);
With the username and password sanitised, we can then set up a SQL command. We're selecting
all the records in the database where the incoming username and password match the database
table fields called L1 and L2:
$SQL = "SELECT * FROM login WHERE L1 = $uname AND L2 = $pword";
Next, issue the SQL command using mysql_query( ):
$result = mysql_query($SQL);
We need to check what is returned by the mysql_query() function. The value in $result will
either be true (if any records are returned) or false (if none are returned). We're checking to see if
there were any errors when the SQL command was issued against the database table. If so, put
something in the error message variable:
if ($result) {
}
else {
$errorMessage = "Error logging on";
}
If the SQL command was issued successfully, you can see how many rows were returned from
the database table. The inbuilt function mysql_num_rows( ) is used for this. If no rows were
returned, then that tells you that there's something wrong with either the username or password.
$num_rows = mysql_num_rows($result);
Next, we test the $num_rows variable to see if it's greater than zero. If it is, then you have a
successful logon. If not, then it's invalid:
if ($num_rows > 0) {
$errorMessage= "logged on ";
}
else {

$errorMessage= "Invalid Logon";


}
In the above code, the number of rows returned could be greater than 1. That would mean that 2
or more people have the same username and password. If you have a website where each user
has to be unique, then you obviously want to check if $num_rows = 1. For some websites, it
doesn't really matter if 2 or more people have the same login details. But for things like forums,
where people are posting and replying to the input of others, then it does matter. After all, you
want to credit forum users with the correct posts. For the purpose of this tutorial, assume that it
doesn't matter if login details are the same.

Setting a Session
So that a user can be remembered across different web pages, you can use something called a
Session. A session is simply the time spent at a particular site or sites. You can store values with
sessions, and these values will be available to all pages on the site. When you close your
browser, the sessions will end. There are quite a lot of ways to use sessions, but we're only
interested in saving a value so that it can be referred to across different pages.
In the previous code, the part that checked if the user was OK was this:
if ($num_rows > 0) {
$errorMessage= "logged on ";
}
else {
$errorMessage= "Invalid Logon";
}
The code checks to see if the number of rows returned from a SQL command is greater than
zero. If it is, then the user is OK. But the code in the login.php script is slightly different. It's this:
if ($num_rows > 0) {
session_start();
$_SESSION['login'] = "1";
header ("Location: page1.php");
}

What the code does is to set up a session variable. The value in the variable will be 1, if the user
logs on successfully. To set up a session variable, you need to issue the start command:
session_start( );
This starts a PHP session. To set up a session variable that you can use to store values, you use
this:
$_SESSION[ ]
In between the square brackets of $_SESSION, you type the name of your variable. Like all
variable names, you can call it almost anything you like. Storing values in the session variable is
just the same as storing values in a normal variable:
$_SESSION['login'] = "1";
After the script runs, you'll have a session variable called 'login' that is set to a value of 1, if the
user is OK. You can then use the "header" function to redirect the user to the page on your site
for members, page1.php in the code above.
header ("Location: page1.php");
For the else part of the if statement, the code is this:
if ($num_rows > 0) {
session_start();
$_SESSION['login'] = "1";
header ("Location: page1.php");
}
else {
$errorMessage = "Invalid Login";
session_start();
$_SESSION['login'] = '';
}
Here, we add something to the error message variable:
$errorMessage = "Invalid Login";
Next, we issue the "start session" command:
session_start();

But the next line puts something different in to the session variable:
$_SESSION['login'] = '';
We're using the same session name (login), but this time we set it to a blank string. If the user
tries to gain access to a restricted part of the site, we'll check for a blank string. A blank string
means that the user hasn't logged on successfully, so we'll redirect them to the login page.
A note of caution here. If you switch cookies off in your browser, the script above refuses to
work! This is because when you use session_start, PHP sends the browser something called a
session ID. This is a long string of letters and numbers. PHP attempts to save the session ID as a
cookie. But it only does this if a line in php.ini from your Apache server is set. This line:
session.use_cookies = 1
If you set this value to 0, then you should be able to log on whether cookies are set or not. The
problem is, there's a good chance that you can't set this to zero. Especially if you have web
hosting with someone else. The solution, in that case, is to check whether cookies are enabled or
not.
You don't actually need PHP to check if cookies are enabled. You can use Javascript. Try this
search string in Google:
javascript +cookies +enabled
You should then find plenty of ideas for scripts. Of course, you'd first need to check if Javascript
is enabled!
And that's about it for the login script. Here's a run down on what we did:

Got the username and password from textboxes on a form

Opened a connection to a database

Validated the username and password

Checked to see if any rows were returned from the database

If rows were returned, set a session variable to 1

If no rows were returned, set a session variable to a blank string

Built up an error message throughout the code

But the point about setting a session variable is so that you can then check its value when users
go to other pages on your site. We'll see how to do that now.

MySQL admin table columns id, username, passcode.


CREATE TABLE admin
(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(30) UNIQUE,
passcode VARCHAR(30)
);

Password Encryption PHP Login Script with Encryption.


Config.php
Database configuration file.
<?php
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'database');
$db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
?>
Login.php
Contains PHP and HTML code.
<?php
include("config.php");
session_start();
if($_SERVER["REQUEST_METHOD"] == "POST")
{
// username and password sent from Form
$myusername=mysqli_real_escape_string($db,$_POST['username']);
$mypassword=mysqli_real_escape_string($db,$_POST['password']);
$sql="SELECT id FROM admin WHERE username='$myusername' and
passcode='$mypassword'";
$result=mysqli_query($db,$sql);
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
$active=$row['active'];

$count=mysqli_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1)
{
session_register("myusername");
$_SESSION['login_user']=$myusername;
header("location: welcome.php");
}
else
{
$error="Your Login Name or Password is invalid";
}
}
?>
<form action="" method="post">
<label>UserName :</label>
<input type="text" name="username"/><br />
<label>Password :</label>
<input type="password" name="password"/><br/>
<input type="submit" value=" Submit "/><br />
</form>
lock.php
Session verification. If no session value page redirect to login.php
<?php
include('config.php');
session_start();
$user_check=$_SESSION['login_user'];
$ses_sql=mysqli_query($db,"select username from admin where username='$user_check' ");
$row=mysqli_fetch_array($ses_sql,MYSQLI_ASSOC);
$login_session=$row['username'];
if(!isset($login_session))
{
header("Location: login.php");
}
?>
welcome.php

<?php
include('lock.php');
?>
<body>
<h1>Welcome <?php echo $login_session; ?></h1>
</body>
logout.php
SignOut Destroy the session value.
<?php
session_start();
if(session_destroy())
{
header("Location: login.php");
}
?>

User Membership With PHP


by Tom Cameron10 Nov 2008412 Comments

13

16

Share

A tutorial for the very beginner! No matter where you go on the Internet, there's a staple that you
find almost everywhere - user registration. Whether you need your users to register for security
or just for an added feature, there is no reason not to do it with this simple tutorial. In this tutorial
we will go over the basics of user management, ending up with a simple Member Area that you
can implement on your own website.

Introduction
In this tutorial we are going to go through each step of making a user management system, along
with an inter-user private messaging system. We are going to do this using PHP, with a MySQL
database for storing all of the user information. This tutorial is aimed at absolute beginners to
PHP, so no prior knowledge at all is required - in fact, you may get a little bored if you are an
experienced PHP user!
This tutorial is intended as a basic introduction to Sessions, and to using Databases in PHP.
Although the end result of this tutorial may not immediately seem useful to you, the skills that
you gain from this tutorial will allow you to go on to produce a membership system of your own;
suiting your own needs.
Before you begin this tutorial, make sure you have on hand the following information:

Database Hostname - this is the server that your database is hosted on, in
most situations this will simply be 'localhost'.

Database Name, Database Username, Database Password - before starting


this tutorial you should create a MySQL database if you have the ability, or
have on hand the information for connecting to an existing database. This
information is needed throughout the tutorial.

If you don't have this information then your hosting provider should be able to provide this to
you.
Now that we've got the formalities out of the way, let's get started on the tutorial!

Step 1 - Initial Configuration


Setting up the database

As stated in the Introduction, you need a database to continue past this point in the tutorial. To
begin with we are going to make a table in this database to store our user information.

The table that we need will store our user information; for our purposes we will use a simple
table, but it would be easy to store more information in extra columns if that is what you need. In
our system we need the following four columns:

UserID (Primary Key)

Username

Password

EmailAddress

In database terms, a Primary Key is the field which uniquely identifies the row. In this case,
UserID will be our Primary Key. As we want this to increment each time a user registers, we will
use the special MySQL option - auto_increment.
The SQL query to create our table is included below, and will usually be run in the 'SQL' tab of
phpMyAdmin.
1 CREATE TABLE `users` (
2 `UserID` INT(25) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
3 `Username` VARCHAR(65) NOT NULL ,
4 `Password` VARCHAR(32) NOT NULL ,
5 `EmailAddress` VARCHAR(255) NOT NULL
6 );

Creating a Base File

In order to simplify the creation of our project, we are going to make a base file that we can
include in each of the files we create. This file will contain the database connection information,
along with certain configuration variables that will help us out along the way.
Start by creating a new file: base.php, and enter in it the following code:
0 <?php
1

session_start();

2
0
3
0 $dbhost = "localhost"; // this will ususally be 'localhost', but can
4 sometimes differ
0 $dbname = "database"; // the name of the database that you are going to use
for this project
5
$dbuser = "username"; // the username that you created, or were given, to

0 access your database


6

$dbpass = "password"; // the password that you created, or were given, to

0 access your database


7

0
8 mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error: " .
mysql_error());

0
mysql_select_db($dbname) or die("MySQL Error: " . mysql_error());
9
1
0

?>

1
1

Let's take a look at a few of those lines shall we? There's a few functions here that we've used
and not yet explained, so let's have a look through them quickly and make sense of them -- if you
already understand the basics of PHP, you may want to skip past this explanation.
1

session_start();

This function starts a session for the new user, and later on in this tutorial we will store
information in this session to allow us to recognize users who have already logged in. If a session
has already been created, this function will recognize that and carry that session over to the next
page.
mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error: " .
mysql_error());

2mysql_select_db($dbname) or die("MySQL Error: " . mysql_error());

Each of these functions performs a separate, but linked task. The mysql_connect function
connects our script to the database server using the information we gave it above, and the
mysql_select_db function then chooses which database to use with the script. If either of the

functions fails to complete, the die function will automatically step in and stop the script from
processing - leaving any users with the message that there was a MySQL Error.

Step 2 - Back to the Frontend


What Do We Need to Do First?

The most important item on our page is the first line of PHP; this line will include the file that we
created above (base.php), and will essentially allow us to access anything from that file in our
current file. We will do this with the following line of of PHP code. Create a file named
index.php, and place this code at the top.
1 <?php include "base.php"; ?>
Begin the HTML Page

The first thing that we are going to do for our frontend is to create a page where users can enter
their details to login, or if they are already logged in a page where they can choose what they
then wish to do. In this tutorial I am presuming that users have basic knowledge of how
HTML/CSS works, and therefore am not going to explain this code in detail; at the moment
these elements will be un-styled, but we will be able to change this later when we create our CSS
stylesheet.
Using the file that we have just created (index.php), enter the following HTML code below the
line of PHP that we have already created.
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

5<title>User Management System (Tom Cameron for NetTuts)</title>


6<link rel="stylesheet" href="style.css" type="text/css" />
7</head>
8<body>
9<div id="main">
What Shall We Show Them?

Before we output the rest of the page we have a few questions to ask ourselves:

1. Is the user already logged in?

Yes - we need to show them a page with options for them to choose.

No - we continue onto the next question.

Has the user already submitted their login details?

Yes - we need to check their details, and if correct we will log them into the
site.

No - we continue onto the next question.

If both of the above were answered No, we can now assume that we need to
display a login form to the user.

These questions are in fact, the same questions that we are going to implement into our PHP
code. We are going to do this in the form of if statements. Without entering anything into any
of your new files, lets take a look at the logic that we are going to use first.
0 <?php
1

if(!empty($_SESSION['LoggedIn']) && !empty($_SESSION['Username']))

0 {
2
// let the user access the main page

0
3 }

0 elseif(!empty($_POST['username']) && !empty($_POST['password']))


4 {
0
5

// let the user login


}

0
else
6
0
7

{
// display the login form

0 }
8

?>

0
9
1

0
1
1
1
2
1
3
1
4

Looks confusing, doesn't it? Let's split it down into smaller sections and go over them one at a
time.
1if(!empty($_SESSION['LoggedIn']) && !empty($_SESSION['Username']))
2{
// let the user access the main page

3
4}

When a user logs into our website, we are going to store their information in a session - at any
point after this we can access that information in a special global PHP array - $_SESSION. We are
using the empty function to check if the variable is empty, with the operator ! in front of it.
Therefore we are saying:
If the variable $_SESSION['LoggedIn'] is not empty and $_SESSION['Username'] is not empty,
execute this piece of code.
The next line works in the same fashion, only this time using the $_POST global array. This array
contains any data that was sent from the login form that we will create later in this tutorial. The
final line will only execute if neither of the previous statements are met; in this case we will
display to the user a login form.
So, now that we understand the logic, let's get some content in between those sections. In your
index.php file, enter the following below what you already have.
0 <?php
1

if(!empty($_SESSION['LoggedIn']) && !empty($_SESSION['Username']))

0{
2

0
3

?>

0
4

<h1>Member Area</h1>
<pThanks for logging in! You are <code><?=$_SESSION['Username']?

0 ></code> and your email address is <code><?=$_SESSION['EmailAddress']?


5 ></code>.</p>
0
6

<?php

0
}
7
elseif(!empty($_POST['username']) && !empty($_POST['password']))

0
8{
0
9

$username = mysql_real_escape_string($_POST['username']);
$password = md5(mysql_real_escape_string($_POST['password']));

1
0
$checklogin = mysql_query("SELECT * FROM users WHERE Username = '".

1 $username."' AND Password = '".$password."'");


1
1
2
1
3
1
4
1
5
1
6

if(mysql_num_rows($checklogin) == 1)
{
$row = mysql_fetch_array($checklogin);
$email = $row['EmailAddress'];

$_SESSION['Username'] = $username;
$_SESSION['EmailAddress'] = $email;
$_SESSION['LoggedIn'] = 1;

1
7
1
8
1

echo "<h1>Success</h1>";
echo "<p>We are now redirecting you to the member area.</p>";

echo "<meta http-equiv='refresh' content='=2;index.php' />";


}

2
0

else

2
1
2
2

{
echo "<h1>Error</h1>";
echo "<p>Sorry, your account could not be found. Please <a
href=\"index.php\">click here to try again</a>.</p>";

2
3

}
}

2
4 else
2{
5

?>

2
6
2
7

<h1>Member Login</h1>

<p>Thanks for visiting! Please either login below, or <a


2
href="register.php">click
here to register</a>.</p>
8

2
9
3
0

<form method="post" action="index.php" name="loginform" id="loginform">


<fieldset>
<label for="username">Username:</label><input type="text"

3 name="username" id="username" /><br />


1

<label for="password">Password:</label><input type="password"

3 name="password" id="password" /><br />


2

<input type="submit" name="login" id="login" value="Login" />

3
3
3
4
3
5

</fieldset>
</form>

<?php

3}
6

?>

3
7
</div>

3
8 </body>
3 </html>
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5

2
5
3
5
4
5
5
5
6
5
7
5
8
5
9

Hopefully, the first and last code blocks won't confuse you too much. What we really need to get
stuck into now is what you've all come to this tutorial for - the PHP code. We're now going to
through the second section one line at a time, and I'll explain what each bit of code here is
intended for.
1$username = mysql_real_escape_string($_POST['username']);
2$password = md5(mysql_real_escape_string($_POST['password']));

There are two functions that need explaining for this. Firstly, mysql_real_escape_string - a
very useful function to clean database input. It isn't a failsafe measure, but this will keep out the
majority of the malicious hackers out there by stripping unwanted parts of whatever has been put
into our login form. Secondly, md5. It would be impossible to go into detail here, but this
function simply encrypts whatever is passed to it - in this case the user's password - to prevent
prying eyes from reading it.
0 $checklogin = mysql_query("SELECT * FROM users WHERE Username = '".
1 $username."' AND Password = '".$password."'");
0
2 if(mysql_num_rows($checklogin) == 1)
0{
3

0
4
0
5
$row = mysql_fetch_array($checklogin);

0
6

$email = $row['EmailAddress'];

0
7

$_SESSION['Username'] = $username;

0
8

$_SESSION['EmailAddress'] = $email;
$_SESSION['LoggedIn'] = 1;

0
9
1
0

Here we have the core of our login code; firstly, we run a query on our database. In this query we
are searching for everything relating to a member, whose username and password match the
values of our $username and $password that the user has provided. On the next line we have an
if statement, in which we are checking how many results we have received - if there aren't any
results, this section won't be processed. But if there is a result, we know that the user does exist,
and so we are going to log them in.
The next two lines are to obtain the user's email address. We already have this information from
the query that we have already run, so we can easily access this information. First, we get an
array of the data that has been retrieved from the database - in this case we are using the PHP
function mysql_fetch_array. I have then assigned the value of the EmailAddress field to a
variable for us to use later.
Now we set the session. We are storing the user's username and email address in the session,
along with a special value for us to know that they have been logged in using this form. After this
is all said and done, they will then be redirect to the Member Area using the META REFRESH in
the code.
So, what does our project currently look like to a user?

Great! It's time to move on now, to making sure that people can actually get into your site.

Let the People Signup

It's all well and good having a login form on your site, but now we need to let user's be able to
use it - we need to make a login form. Make a file called register.php and put the following
code into it.
0 <?php include "base.php"; ?>
1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"


0 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

2 <html xmlns="http://www.w3.org/1999/xhtml">
0 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
3
0
4 <title>User Management System (Tom Cameron for NetTuts)</title>
<link rel="stylesheet" href="style.css" type="text/css" />

0
5 </head>
0 <body>
6

<div id="main">

0
<?php
7
if(!empty($_POST['username']) && !empty($_POST['password']))

0
8{
0
9
1
0
1
1
1
2
1
3
1
4
1

$username = mysql_real_escape_string($_POST['username']);
$password = md5(mysql_real_escape_string($_POST['password']));
$email = mysql_real_escape_string($_POST['email']);

$checkusername = mysql_query("SELECT * FROM users WHERE Username = '".


$username."'");

if(mysql_num_rows($checkusername) == 1)
{
echo "<h1>Error</h1>";
echo "<p>Sorry, that username is taken. Please go back and try

5 again.</p>";
}

1
6

else

1
7

{
$registerquery = mysql_query("INSERT INTO users (Username, Password,

1 EmailAddress) VALUES('".$username."', '".$password."', '".$email."')");


8
if($registerquery)

1
9
2
0
2
1

{
echo "<h1>Success</h1>";
echo "<p>Your account was successfully created. Please <a
href=\"index.php\">click here to login</a>.</p>";
}
else

2
2

2
3

echo "<h1>Error</h1>";
echo "<p>Sorry, your registration failed. Please go back and try

2 again.</p>";
4

2
5

}
}

2
6 else
2
7

{
?>

2
8
<h1>Register</h1>

2
9
3
0
3
1

<p>Please enter your details below to register.</p>

<form method="post" action="register.php" name="registerform"

3 id="registerform">
2
<fieldset>

3
<label for="username">Username:</label><input type="text"
3 name="username" id="username" /><br />
3
<label for="password">Password:</label><input type="password"
4 name="password" id="password" /><br />
<label for="email">Email Address:</label><input type="text"
3
5 name="email" id="email" /><br />
<input type="submit" name="register" id="register" value="Register" />

3
6

</fieldset>

3
7

</form>

3
8

<?php

3}
9 ?>
4
0
</div>

4
1 </body>
4
2
4
3
4
4
4
5
4
6
4
7
4

</html>

8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3

So, there's not much new PHP that we haven't yet learned in that section. Let's just take a quick
look at that SQL query though, and see if we can figure out what it's doing.

$registerquery = mysql_query("INSERT INTO users (Username, Password,

1EmailAddress) VALUES('".$username."', '".$password."', '".$email."')");

So, here we are adding the user to our database. This time, instead of retrieving data we're
inserting it; so we're specifying first what columns we are entering data into (don't forget, our
UserID will go up automatically). In the VALUES() area, we're telling it what to put in each
column; in this case our variables that came from the user's input. So, let's give it a try; once
you've made an account on your brand-new registration form, here's what you'll see for the
Member's Area.

Make Sure That They Can Logout

We're almost at the end of this section, but there's one more thing we need before we're done here
- a way for user's to logout of their accounts. This is very easy to do (fortunately for us); create a
new filed named logout.php and enter the following into it.
1<?php include "base.php"; $_SESSION = array(); session_destroy(); ?>
2<meta http-equiv="refresh" content="0;index.php">

In this we are first resetting our the global $_SESSION array, and then we are destroying the
session entirely.
And that's the end of that section, and the end of the PHP code. Let's now move onto our final
section.
Advertisement

Step 3 - Get Styled


I'm not going to explain much in this section - if you don't understand HTML/CSS I would
highly recommend when of the many excellent tutorials on this website to get you started. Create
a new file named style.css and enter the following into it; this will style all of the pages that
we have created so far.
01 * {
02

margin: 0;

03

padding: 0;

04
05

}
body {

06

font-family: Trebuchet MS;

07 }
08 a {
color: #000;

09
10
11

}
a:hover, a:active, a:visited {
text-decoration: none;

12
}

13

#main {

14

width: 780px;

15

margin: 0 auto;

16

margin-top: 50px;

17

padding: 10px;

18

border: 1px solid #CCC;

19

background-color: #EEE;

20 }
21 form fieldset { border: 0; }
22 form fieldset p br { clear: left; }
23

label {
margin-top: 5px;

24

display: block;

25

width: 100px;

26

padding: 0;

27
28
29
30
31

float: left;
}
input {
font-family: Trebuchet MS;
border: 1px solid #CCC;

32
33

margin-bottom: 5px;

34

background-color: #FFF;

35

padding: 2px;

36 }
37 input:hover {
38

border: 1px solid #222;

39

background-color: #EEE;

40

41

Now let's take a look at a few screenshots of what our final project should look like:

The login form.

The member area.

The registration form.


http://code.tutsplus.com/tutorials/user-membership-with-php--net-1523

Das könnte Ihnen auch gefallen