Password protecting a site

cwarn23 5 Tallied Votes 2K Views Share

Making sites is nice and fun but what if you don't want everybody too see something like an admin panel or maybe a special button. Well this tutorial helps you understand how to add a password to a php site in a simple manner. There are two techniques you can use. One is to use a database which allows you to have a group of users who may access the site. Another technique is to have pre defined variables that check if the values match the value of the variable. In this tutorial you will get to know the basics while following the method of entering users into a php file. Please note all passwords should be hashed but this is a tutorial and I kept it as simple as possible.

To use a variable stored in your site configuration file (eg config.php if you have one) you simply do the following:

<?php //config.php
$users[0]['name']='cwarn23';
$users[0]['password']='password';
$users[1]['name']='root';
$users[1]['password']='drowssap';
?>

Now you will notice that there is an array of users that may use the site along with their passwords. Normally for security reasons the password would be salted on both sides of the string. Then hashed, then substr() then finally rehashed. Note you should never use crc32 or crc32b as a hashing algorithm but for now lets see how to check if the user has loged in. To do that we need a html form. So lets make one.

<form method="post" action="">
Username: <input type="text" name="user" /><br />
Password: <input type="password" name="password" />
<input type="submit" value="Login" name="login" />

Above is a simple html form which you may use for a login script and you can sign in with any number of users provided php as been taught who can sign in with what password. For php to know this we will need to add in some php code. So for a demonstration script I shall show the following script then explain what each section does.

<?php //index.php
session_start();
$error='';
require('config.php');

/* pass by the dreaded magic quotes */
if (isset($_POST) && !empty($_POST)) {
    function post($value) {
        $value = is_array($value) ? array_map('post', $value) : stripslashes($value);
        return $value;
        }
    if(get_magic_quotes_gpc()) {
        //magic quotes enabled
        $_POST=post($_POST);
        }
}

/* user validation upon login */
if (isset($_POST['login'])) {
    for ($i=0;$i<count($users);$i++) {
        if ($_POST['user']==$users[$i]['name'] && $_POST['password']==$users[$i]['password']) {
            $_SESSION['user']=$_POST['user'];
            break;
            }
        }
    if (!isset($_SESSION['user'])) {
        $error='Access denied. Please try again.';
        }
    }

/* display login or success screen */
if (!isset($_SESSION['user'])) {
echo <<< DATA
<form method="post" action="">
Username: <input type="text" name="user" /><br />
Password: <input type="password" name="password" />
<input type="submit" value="Login" name="login" />
DATA;
echo "<br />\n".$error; //display error
} else {
echo 'you are logged in '.$_SESSION['user'];
unset($_SESSION['user']); //log out
}

Ok. So that's one big script for a tiny job but all of the concepts are in there for a login script which uses a php file to store the passwords. So now I guess I have some explaining to do.
As you will notice near the top of the file is require('config.php'); . This is to include the file posted earlier which had the $users[][] array. Also you will notice that in this instance I used require instead of require. One might ask what is the difference? Well although their identical functions there is one tiny difference. the require() function uses a little more cpu for debugging purposes in the event that it cannot include the file. If you know the file exists and that it doesn't ever get altered then include() function is safe. However to add new users we need to delete the file and upload it again and if somebody attempts to login while you are uploading the new file then php can't handle the error as efficiently. So if for example you were to include/require another file for something that doesn't change like an api then in that situation it would be best to use the include() function. So conclusion, use the require function unless you know you won't be deleting, renaming or updating the included file.

Next is the section I have written for magic quotes. A lot of developers don't write this part and go as far as to deny that magic quotes exist but it is indeed a purposely built bug/feature in php that we need to work around. What happens with magic quotes is when you post a variable to php with method="post", all of the ' and " symbols will be proceeded with a backslash resulting in \' and \". So we need to use the strip slashes function to remove those slashes. However on some servers web hosts have disabled magic quotes for you and other hosts have php versions which don't support magic quotes making it more complicated. That is where the “if statement” comes in to check if those slashes exist before removing them.

Now for the validation. The first thing you will need to do before the validation is to check if the form has been submitted. To do this simply give the give the submit button on your html form a name for the name="name" or in this case name="login". This is then processed through an “if statement” to see if the form has been submitted. So if it's not posted then it won't be set there by going to the next piece of code. In case your wondering the isset() function checks if a variable has been defined meaning if the form has been posted the $_POST will be defined there by going to the next section.

After the “if” statement is a “for loop” within the validation section. “For loops” are easy when you learn but not many people explain them well making it harder to learn than necessary. The easiest way to think of a for loop is a while loop with bonus features and less cpu consumption when dealing with numbers. So if for instance we were to convert the loop into a while loop it would be as follows.

$i=0;
    while ($i<count($users)) {
        if ($_POST['user']==$users[$i]['name'] && $_POST['password']==$users[$i]['password']) {
            $_SESSION['user']=$_POST['user'];
            break;
            }
        $i++; // same as $i+=1;
        }

So if you compare the syntax you will see that a for loop is divided into for sections divided by a ; symbol. The first section is what comes before the loop so it's like a variable being defined or assigned a value. The second section is the same as in the while loop where it returns true or false so the loop knows when to stop. And the third is what happens at the end of each loop. So the variable which was just defined could have some math done on it. In this case we simply have the variable $i assigned 0 at the beginning and at the end of each loop +1 is added to the variable $i and in the middle it checks if $i is smaller than the number of users that exist so it knows when to stop checking. In case you did not know the count() function counts how many values are in the array. In this case we have a 2d array meaning there is two [] symbols. However the count function only counts how many unique entries are in the first [] symbol (eg $users[1]) resulting in two as its returned answer.

Following the for loop or in the script above the while loop there is an if statement. This if statement checks if the posted username ($_POST) matches the user in the $users array ($users[$i]) and the same for the password. There is a trick there however because in the $users array there are two users and you can only check one user at a time. That is where the loop comes in. The variable $i as used in the loop will choose which user to compare with as $i is entered into $users[$i]['name'] along with $users[$i]['password'] and the loop will keep on adding +1 to $i until it reaches the last user or finds a match. So if it does match the username and password then the $_SESSION will be assigned the name of the user. That's all you need to do to log the user in. To check if the user is logged in just use the isset() function as later described. The $_SESSION array can be viewed across multiple pages without having to put the variable in the url so makes it quite convenient for a login system but keep in mind never put passwords into the $_SESSION array. Not even hashed passwords because it's not secure and not necessary. Just after the username has been added to the session array you will see the word break; . That piece of code basically exits the loop to save some time and recourses.

Now that we have gone through the validation process lets see how to check if the user is logged in or not. To check if a user is not logged in simply use the if statement if (!isset($_SESSION['user'])) { and that will check if the user is logged in or not. How it does this is from the following piece of code:

$_SESSION['user']=$_POST['user'];

When that piece of code is executed it assigns a value to $_SESSION there by making it set. So to check if the user is not logged in you need to check if $_SESSION is not set. This can be accomplished by putting the ! symbol before the function so that now it checks if notset. In case you didn't understand that bit the ! symbol basically converts the functions result from true to false vice versa. Now if you check inside the “if statement” it is a simple variable assignment for the error. So basically the result of this section is if the user is not logged then assign an error to the error variable which will be displayed later.

Near the very end is yet again the same if statement we just used. That is to check if the user is not loged in. if it passes the “if condition” it then displays a html form. Don't mind the fancy way of displaying html as it was just neater. After it has echoed the data you will see in the script that there is a second echo function before the else. This echo function will display the error that was assigned earlier. So if a user tries to login with the wrong password they will get an error message. Now that we have done the “if statement” there is the else statement. Basically the else returns what to do in the event that the “if statement” is not true. So we will need to tell it what to do if the user is logged in. We shall give them a fancy message saying they are logged in and display their user name which is stored in $_SESSION from when $_POST got assigned to it. And if you want to ever log the user out meaning to can't browse around the members only area any more simply use the unset function on the $_SESSION variable.

So that is the basics on how to run a login script if you want to enter all of the users into a php file which I would not recommend but is good for basic non important things like visitor stats and hiding favorites links and hiding porn.

happygeek commented: thanks for the tutorial +12
scarcella commented: Very well written! +3
mathieu89 14 Light Poster

Hi,

This is a great post. I wanted to ask you a few questions about the security. I use a very similiar login method on one of my websites and i have read alot about this topic and many other tutorials suggest using sessions with hash, salt, session id, ip, timestamp ect. Do you think that your example is secure? I dont really want to go to the extremes suggested in many other tutorials becuase i dont store sensitive information.

cwarn23 387 Occupation: Genius Team Colleague Featured Poster

Hi,

This is a great post. I wanted to ask you a few questions about the security. I use a very similiar login method on one of my websites and i have read alot about this topic and many other tutorials suggest using sessions with hash, salt, session id, ip, timestamp ect. Do you think that your example is secure? I dont really want to go to the extremes suggested in many other tutorials becuase i dont store sensitive information.

Well in regards to security this tutorial was designed to be simple and easy to use but as per security, it is not your most secure option. The reason being is if the apache service fails then somebody may be able to gain access to the passwords however this tutorial is to gain knowledge of the basic concepts of how to create a login system. To keep it simple I have removed hashes from the tutorial because it would cause a lot of confusion for noobies but I will give the following example of how to create a hash for a password which will automatically salt the password and make it a secure hash.

<?php
function securehash($string) {
return sha1(substr(sha1($string),13,-13).$string.md5($string));
}

Then you can use the securehash function to hash all of your passwords and will automatically create the salts. But if I had of used the securehash() function in the above tutorial it would have made it a lot more difficult to enter in the passwords into the array and that is why I shall save hashes for a separate tutorial. :)

<M/> 170 Why so serious? Featured Poster

This post is really helpful :)

Gideon_1 15 Junior Poster

Awesome, its really cool.

Rennie_1 -9 Newbie Poster

you need to use md5 to encrypt your site password.

happygeek commented: What he said +0
JamesCherrill commented: Absolutely wrong. MD5 is compromised and should not be used for security purposes -3
Member Avatar for diafol
diafol

This may be a response to a necropost but may be worth mentioning. The original post was written 4 years ago. Things can move quickly wrt security. Please see password_hash() and password_verify()

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.