954,576 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Login System

Hello All,
I want to make a CD/DVD Library where by an admin can do all the operations while any other norma user can do limited operations (simply browsing and searching). I'm still organizing and doing simple design and I need your opinions on this:
1. What is the best login technique (after storing users and passwords in database?). I can get usernames from database as well as from login forms but I'm not sure how to implement comparison the best way!

2. What is the best way of storing password? (secure way)

3. How do I redirect them to the right page after successful login

4. How do I prevent any unlogged user from accessing the Library script

Any answer to any question is appreciated

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

Here is something I typed up a while ago. Its a complete login and registration system. Just create the following pages and create the database and tables. After that it should work.

This system is safe from sql injection, spam bots, and cross-site request forgery. It doesn't have any xss holes.

PHP/MYSQL USER REGISTRATION AND LOGIN EXAMPLE

Database table
-------------------------------------------------------------
Todo - Create this table in your database

CREATE TABLE `login` (
`id` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR( 30 ) NOT NULL ,
`password` VARCHAR( 100 ) NOT NULL ,
PRIMARY KEY ( `id` ) ,
UNIQUE ( `username` )
) ENGINE = MYISAM


Database connection page - includes/dbconnect.php
-------------------------------------------------------------
Description - Holds database connection. This is used to get rid of redundant code in each page. It also helps if you change your username/password/database name you won't have to update every page, just one.
Todo - Fill the variables with the proper information

<?php

$host = 'localhost';
$user = '';
$pass = '';
$dbname = '';

$con = mysql_connect( $host,$user,$pass ) or die('Unable to connect');
mysql_select_db( $dbname ) or die('Unable to select database');

?>


Functions page - includes/functions.php
-------------------------------------------------------------
Description - Holds the functions. Used so you don't have to repeat the functions in each page. Also, if you need to update a function, you only will have to do it once.

<?php

function encryptPassword( $pass,$salt=false,$saltLength=4 ) {
		if ( $salt === false ) {
			$res = '';
			for( $i=0;$i<$saltLength;$i++ ) {
				$res .= pack( 's',mt_rand() );
			}
			$salt = substr( base64_encode( $res ),0,$saltLength );
		}
		return $salt . sha1( $salt . $pass );
}
	
function checkPassword( $pass,$hash,$saltLength=4 ) {
		if ( encryptPassword( $pass,substr( $hash,0,$saltLength ) ) === $hash ) {
			return true;
		}
		return false;
}

?>


Registration page - register.php
-------------------------------------------------------------
Description - Gets username and password from user, validates them, and inserts into database

<?php

session_start();

require('includes/functions.php'); //include functions
require('includes/dbconnect.php'); //include db connection

$min_form_time = 5; //in seconds
$max_form_time = 30; //in seconds

$error = array(); //define $error to prevent error later in script
$message = '';
if ( isset( $_POST['submit'] ) ) {
    $error = array();
    array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection
    $user = $_POST['username'];
    $pass = $_POST['password'];
    $token = $_POST['token'];
    if ( $token !== $_SESSION['token'] ) {
        $error[] = 'Token is invalid';
    }
    else {
        if ( time() <= ( $_SESSION['time'] + $min_form_time ) ) {
            $error[] = 'Form submitted too quickly, please slow down and try again';
        }
        elseif ( time() >= ( $_SESSION['time'] + $max_form_time ) ) {
            $error[] = 'Form has expired';
        }
        else {
            if ( empty( $user ) ) { //check if username is blank
                $error[] = 'Username is blank';
            }
            elseif ( strlen( $user ) > 30 ) { //make sure the username is not longer than 30 chars
                $error[] = 'Username is longer than 30 characters';
            }
            else { //if there aren't any errors with $user at this point, check to make sure no one else has the same username
                $query = mysql_query( "SELECT * FROM `login` WHERE `username` = '{$user}'",$con );
                if ( mysql_num_rows( $query ) > 0 ) {
                    $error[] = 'Username already exists';
                }
            }
            if ( empty( $pass ) ) { //check if password is blank
                $error[] = 'Password is blank';
            }
            elseif ( strlen( $pass ) < 9 ) { //make sure password is longer than 8 characters
                $error[] = 'Password must be longer than 8 characters';
            }
            elseif ( !preg_match( "/^.*(?=.{3,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/",$pass ) ) { //check to see if its a valid password
                $error[] = 'Password invalid - it must contain at least 1 number, 1 uppercase letter, 1 lowercase letter';
            }
            if ( count( $error ) == 0 ) { //if there are no errors, then insert into database
                $pass = encryptPassword( $pass ); //hash password before inserting into database
                $query = mysql_query( "INSERT INTO `login` (`username`,`password`) VALUES ('{$user}','{$pass}')",$con );
                $message = 'User registration successful!';
            }
        }
    }
}

$errmsg = '';
if ( count( $error ) > 0 ) { //if there are errors, build the error list to be displayed.
    $errmsg = '<div>Errors:<ul>';
    foreach( $error as $err ) { //loop through errors and put then in the list
        $errmsg .= "<li>{$err}</li>";
    }
    $errmsg .= '</ul></div>';
}

$token = md5(uniqid(rand(),true));
$_SESSION['token'] = $token;
$_SESSION['time'] = time();

$html =<<<HTML
<html>
<head>
<title>Registration</title>
</head>
<body>
    <h3>Member Registration</h3>
    {$errmsg}
    <div>
        <form action="{$_SERVER['PHP_SELF']}" method="post">
            Username: <input type="text" name="username" />
            Password: <input type="password" name="password" />
            <input type="hidden" name="token" value="{$token}" />
            <input type="submit" name="submit" value="Register" />
        </form>
    </div>
    <div style="color:#ff0000">{$message}</div>
</body>
</html>
HTML;

echo $html;

?>


Login page - login.php
-------------------------------------------------------------
Description - Gets username and password from user, validates them, and check to see if user is present in database and sets a session.

<?php

session_start(); //start session so we can login

require('includes/functions.php'); //include functions
require('includes/dbconnect.php'); //include database connection

$min_form_time = 5; //in seconds
$max_form_time = 30; //in seconds

$error = array(); //define $error to prevent error later in script.
if ( isset( $_POST['submit'] ) ) {
    $error = array();
    array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection
    $user = $_POST['username'];
    $pass = $_POST['password'];
    $token = $_POST['token'];
    if ( $token !== $_SESSION['token'] ) {
        $error[] = 'Token is invalid';
    }
    else {
        if ( time() <= ( $_SESSION['time'] + $min_form_time ) ) {
            $error[] = 'Form submitted too quickly, please slow down and try again';
        }
        elseif ( time() >= ( $_SESSION['time'] + $max_form_time ) ) {
            $error[] = 'Form has expired';
        }
        else {
            if ( empty( $user ) ) { //check if username is blank
                $error[] = 'Username is blank';
            }
            elseif ( strlen( $user ) > 30 ) { //make sure the username is not longer than 30 chars
                $error[] = 'Username is longer than 30 characters';
            }
            if ( empty( $pass ) ) { //check if password is blank
                $error[] = 'Password is blank';
            }
            elseif ( strlen( $pass ) < 9 ) { //make sure password is longer than 8 characters
                $error[] = 'Password must be longer than 8 characters';
            }
            elseif ( !preg_match( "/^.*(?=.{3,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/",$pass ) ) { //check to see if its a valid password
                $error[] = 'Password invalid - it must contain at least 1 number, 1 uppercase letter, 1 lowercase letter';
            }
            if ( count( $error ) == 0 ) { //if everything is ok so far, keep going (i do this because i don't want to hit the database if the username or password is blank)
                $query = mysql_query( "SELECT `id`,`password` FROM `login` WHERE `username` = '{$user}' LIMIT 1",$con );
                if ( mysql_num_rows( $query ) !== 1 ) { //checks to see if a row was found with username provided by user
                    $error[] = 'Username and/or Password incorrect'; //never be specific with errors, makes it hard to crack
                }
                else {
                    list( $id,$hash ) = mysql_fetch_row( $query ); //puts the id and password from result into $id and $pass variables
                    if ( !checkPassword( $pass,$hash ) ) { //check password from user against the hash in the database.
                        $error[] = 'Username and/or Password incorrect';
                    }
                    if ( count( $error ) == 0 ) { //if now errors found, then set session for login
                        $_SESSION['auth'] = $id;
                        header('Location: member.php'); //redirect to <strong class="highlight">secure</strong> area
                        exit; //exit script since we are redirecting anyway
                    }
                }
            }
        }
    }
}

$errmsg = '';
if ( count( $error ) > 0 ) { //if there are errors, build the error list to be displayed.
    $errmsg = '<div>Errors:<ul>';
    foreach( $error as $err ) { //loop through errors and put then in the list
        $errmsg .= "<li>{$err}</li>";
    }
    $errmsg .= '</ul></div>';
}

$token = md5(uniqid(rand(),true));
$_SESSION['token'] = $token;
$_SESSION['time'] = time();

$html =<<<HTML
<html>
<head>
<title>Login</title>
</head>
<body>
    <h3>Member Login</h3>
    {$errmsg}
    <div>
        <form action="{$_SERVER['PHP_SELF']}" method="post">
            Username: <input type="text" name="username" />
            Password: <input type="password" name="password" />
            <input type="hidden" name="token" value="{$token}" />
            <input type="submit" name="submit" value="Login" />
        </form>
    </div>
</body>
</html>
HTML;

echo $html;

?>


Member area - member.php
-------------------------------------------------------------
Description - place where people who are successfully logged in go. Information on this page is only for members to access, no one else can see it.

<?php

session_start(); //start session so we can see if the user is logged in.

if ( !isset( $_SESSION['auth'] ) ) { // if auth is not in the $_SESSION array (meaning they haven't been to the login page where its set) redirect them to the login page
    header('Location: login.php');
    exit;
}

require('includes/dbconnect.php'); //include database connection

$memid = $_SESSION['auth']; //set member id into $memid.

$query = mysql_query( "SELECT `username` FROM `login` WHERE `id` = {$memid}" ); //
$member = mysql_fetch_assoc( $query );

echo "Welcome, {$member['username']} <a href=\"logout.php\">Logout</a>";

?>


Logout page - logout.php
-------------------------------------------------------------
Description - logs out member and redirects to login page

<?php

session_start(); //start session so we can logout

unset( $_SESSION['auth'] ); //remove auth from the $_SESSION array

header('Location: login.php');
exit;

?>
kkeith29
Nearly a Posting Virtuoso
1,357 posts since Jun 2007
Reputation Points: 235
Solved Threads: 194
 

Try this: http://evolt.org/node/60384
Admin/user

If you want multiple login with the number of cashier, supervisor etc...
Admin/master/agent/user/guest
http://sourceforge.net/projects/phploginsystemw/

phpbeginners
Posting Whiz in Training
226 posts since Jul 2009
Reputation Points: 12
Solved Threads: 32
 

above code looks nice. try it

BzzBee
Posting Whiz
327 posts since Apr 2009
Reputation Points: 16
Solved Threads: 48
 

Thanks alot KKeith29,
I failed to add to you some reputation points. I wonder why. That option isn't there in your username
Bravo!

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

does the above code prevents multiple login

j_limboo
Junior Poster in Training
70 posts since Sep 2009
Reputation Points: 10
Solved Threads: 0
 

No. It can though. It wouldn't be hard to add.

kkeith29
Nearly a Posting Virtuoso
1,357 posts since Jun 2007
Reputation Points: 235
Solved Threads: 194
 

what lines and tables need to be added to prevent multiple logins

j_limboo
Junior Poster in Training
70 posts since Sep 2009
Reputation Points: 10
Solved Threads: 0
 

lets take this code to the next level

j_limboo
Junior Poster in Training
70 posts since Sep 2009
Reputation Points: 10
Solved Threads: 0
 

I tried to use the above code for an example and i came across a Deprecated on Call-time pass-by-reference for these following code:

array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection


.

can anyone assist me on this? thanks

futhonguy
Junior Poster in Training
69 posts since Oct 2009
Reputation Points: 10
Solved Threads: 0
 

Use:

$_POST = array_map( 'mysql_real_escape_string',array_map( 'stripslashes',$_POST ) );
kkeith29
Nearly a Posting Virtuoso
1,357 posts since Jun 2007
Reputation Points: 235
Solved Threads: 194
 

I tried to use the above code for an example and i came across a Deprecated on Call-time pass-by-reference for these following code:

array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection

.

can anyone assist me on this? thanks

Use

array_map('stripslashes,$_POST); 
array_map('mysql_real_escape_string',$_POST);

Here is a quote from php.net .
There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.

nav33n
Purple hazed!
Moderator
4,465 posts since Nov 2007
Reputation Points: 524
Solved Threads: 356
 

[QUOTE=futhonguy;1055694]I tried to use the above code for an example and i came across a Deprecated on Call-time pass-by-reference for these following code:

array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection


.

put below code.....

array_map( 'stripslashes',$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',$_POST ); //Escapes data to protect against sql injection
muralikalpana
Posting Pro
540 posts since Sep 2009
Reputation Points: 21
Solved Threads: 36
 

I tried to use the above code for an example and i came across a Deprecated on Call-time pass-by-reference for these following code:

array_map( 'stripslashes',&$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',&$_POST ); //Escapes data to protect against sql injection

.

can anyone assist me on this? thanks

It is good warning -- That you use later version that Keith's
This works without warning

array_map( 'stripslashes',$_POST ); //Strips slashes
    array_map( 'mysql_real_escape_string',$_POST ); //Escapes data to protect against sql injection


.

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

Try this: http://evolt.org/node/60384 Admin/user

If you want multiple login with the number of cashier, supervisor etc... Admin/master/agent/user/guest http://sourceforge.net/projects/phploginsystemw/


Hey, I was wondering if you know how to change the username login to email login from the evolt.org website

Thanks

andrewliu
Junior Poster
188 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

Thread is dead old and marked solved!
Start new thread!

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You