PHP - Encrypting Passwords

This 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 signup.php.
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 Register button.
It will look like this:

Type a username and password, and make a note of the them, as you'll be needing
these details for the login page.

Click the button to register, and you should see "item inserted"
printed to the page:

Open up the signup.php script and take a look at the code. (It's one
of the files you downloaded from here: scripts.)
The HTML for this form can be seen at the bottom of the page. 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 = "";

The next part of the code is where we check to see if the form has been POSTED
or not (was the Register button clicked):

We have two sets of dot/dot/slash now before require configure.php.
This is because we created a folder for ourselves to hold the login scripts.
The root folder (the www one) would be one folder up from this new folder. However,
as stated in a previous tutorial, it's a bad idea to place your login credentials
in the root folder. Our login credentials are outside of the root folder, hence
the two sets of dot/dot/slash.

We then create a new mysqli object passing in all those constants we
set up in the configure file. (SEE HERE, if you skipped
this lesson.)

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 is found, then we set up a prepared statement:

$SQL = $db_found->prepare('SELECT * FROM login WHERE
L1 = ?');

$SQL->bind_param('s', $uname);
$SQL->execute();

Notice the SQL in the first line:

SELECT * FROM login WHERE L1 = ?

We only want to select the L1 column, which is the username. We're going to
make sure that this column is a unique value, meaning you can't have two people
with the same username. To do that, we need to get the results from the SQL
query:

$result = $SQL->get_result();

If any results are returned, then we know that the username is taken. So we
can display a message:

if ($result->num_rows > 0) {

$errorMessage = "Username already taken";

}

If no results are returned, then we can go ahead and add the chosen username
to the database.

The PHP function password_hash is an inbuilt one. In between the round
brackets of password_hash you need some text you want to encrypt. After a comma,
you specify the encryption algorithm that you want to use. You can either use
PASSWORD_DEFAULT or PASSWORD_BCRYPT here. These two are inbuilt constants. PASSWORD_DEFAULT
gets you the bcrypt algorithm. It's recommended that you created a field in
your database 255 characters long. Rather confusingly, PASSWORD_BCRYPT use the
crypt_blowfish algorithm. For more information on these two algorithms see here:

Once password_hash has done its work, it will either return you a hashed (and
salted) password, or it will return false, if something went wrong. (You could
set up an if statement to test for this, if you wanted.)

Once we have a hashed password, we can setup another prepare statement:

So we're INSERT INTO with our two database table fields L1 and L2. The VALUES
are question mark placeholders. The next line binds these parameters:

$SQL->bind_param('ss', $uname, $phash);

We then only need to execute and print something out:

$SQL->execute();
header ("Location: login.php");

The last line redirects the new user to the login page. If you took the user's
email address you could also send them something to let them know they have
been successful. But please don't email them their new password in plain text!