Creating a secure login is a fairly simple task...
If you know what you're doing. Here are the steps
you need to take:
Home
Discuss on DevNetwork
View the Demonstration
Creating the Database
At its simplest, your user database must contain the following information:
Id - int auto_increment primary_key
Username - varchar(100)
Password - varchar(100)
Salt - varchar(100)
Using a mysql database, you can create this using the following SQL:
CREATE TABLE IF NOT EXISTS 'users' (
'id' INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
'user' VARCHAR(100) NOT NULL,
'pass' VARCHAR(100) NOT NULL,
'salt' VARCHAR(100) NOT NULL,
);
You may find it easier to do this using phpadmin (if installed on your server):
Navigate to the database you wish to use.
Near the bottom you can create a new table.
Fill in the required information as above.
Front End Manipulation
Before we send data from the client side to the server, it is helpful to do some
work protecting the user's information. We will use Javascript to hash the user
password initially. This is to prevent the password from being detected while it
is transmitted in plaintext. Because we're using Javascript, however, it is
important to remember that this is NOT highly secure. This is just an additional
security measure we are taking.
First, modify the forms to call the protect() function like so:
<form action="register.php" method="post" onsubmit="protect()">
Next, download the javascript
here, originally by
Angel Marin.
Once you have everything unpacked, include the following in your page's head:
<script type="text/javascript" src="sha256.js"></script>
<script type="text/javascript">
function protect(frm) {
var tmp;
var x = document.getElementById(frm);
for(var i=0; i<x.length; i++) {
tmp = x.elements[i];
if(tmp.name=="pass" || tmp.name=="pass2")
tmp.value = hex_sha256(tmp.value);
if(tmp.name=="js_on")
tmp.value = "yes";
}
}
</script>
This will cause the value of the password fields to be set to the sha256 hash of
the user's password. Hence, no plaintext password is sent. Yay!
Back End Manipulation
This task is the tricky bit. I won't reproduce the code here because you can
download it from the
Demo. I'll explain in order what each task is that
we need to complete for register, then for login. The numbers correspond to
comments labeled "//comment #X" in back/register.php and back/login.php respectively.
back/register.php:
- Validate username
- Validate password
- Check if Javascript was on. If not, perform initial hashing
- Generate salt
- Hash combination of unique user salt, user password, and server-wide "super salt"
- Store all values into database
- If successful, redirect to login page otherwise to register page.
back/login.php:
- Validate username
- Validate password
- Check if Javascript was on. If not, perform initial hashing
- Retrieve user's password hash and salt
- Hash combination of unique user salt, user password, and server-wide "super salt"
- Check password
- (optional) on success of 6, create new user salt
- Set session data
- If successful, redirect to [wherever] otherwise to login page.
Tracking Information
We use sessions to keep track of user information including logged in status,
a user's name, maybe permissions he has... anything of that nature. I like to
use sessions to handle errors as well since they're simple to deal with. It is
important to remember to destroy sessions when a user logs out. It's not a
bad idea to keep track of when the last time a user did anything either. So,
with that in mind, examples can be found by searching for the following
comments in these pages of the
Demo:
index.php:
Error retrieval "//errs"
logout.php:
Destroy session "//destroy"
loggedOnly.php:
Update idle time (and possibly force logout) "//idle"