How to create secure login with PHP, MYSQL and PostgreSQL


Password hashing is the most basic security you will need to do if your application accepts passwords from users. If you do not hash your passwords, the passwords stored in your application’s database can be stolen and can be used to compromise user’s information as well as your system.

What is hashing?

In simple terms, hashing means converting a plain text into a fixed-size string of characters called hash value or simply hash. Hashing is done by using a hash function, also called a hashing algorithm. For a particular hashing function, the resultant hash is the same size (fixed size) regardless of the plain text size.

The most important property of the hash function is that it is one-way i.e. you can generate a hash from plain text and not the reverse.

However, brute force (computing hashes for all possible string combinations) can be used to ‘guess’ the plain text from which as a hash was obtained from. With sufficient computing power, it should be quick to make a guess!

Hashing algorithm 

Examples of hash functions

MD5 and SHA1 are common examples of hashing algorithms, which have been implemented in the PHP language. However, with increased computing power, they have been found unsuitable for hashing passwords because brute force can be used to reverse hashes to obtain original plain text.

How can one hash passwords in PHP?

Proper hashing should achieve the following:

  1. Hashing should be one-way i.e. should be very difficult, nearly impossible or computationally and prohibitively expensive to reverse a hash.
  2. Even when the plain texts are similar, the hash values should be different. This has two advantages;- i) Users using a similar password in an application have different hashes and ii) Protects password database from rainbow attacks.

We have earlier explained the first point.

In the second point, how do we ensure that similar plain text produces different hashes? By using a salt or commonly known as cryptographic salt.

How does applying a salt protect the password database from rainbow attacks?

What is a cryptographic salt?

A salt is a random text, which is appended to the plain text password before it is hashed. It makes it difficult for attackers to determine plain text for hashes using pre-calculated hashes corresponding to plain text. A salt also ensures that users, who chose the same password end up having different hashes.

Before the password is hashed, a cryptographic salt is added

How is a rainbow table used to attack password databases?

A rainbow table can contain millions or even billions of records of pairs of pre-computed plain text and hashes. To understand how rainbow tables are used to attack applications, which do not use cryptographic salts, study the table a, b & c below. Note that the hashes are not generated from any particular hashing algorithm. We have used them for illustration purposes.

Table a: Rainbow table containing pairs of plain text password and pre-computed hash values. This table belongs to the attackers and can contain billions of passwords by generating possibly the from character combination.

Plain text passwordPassword hash
and more…

Table b: Passwords database for an application, which does not use cryptographic salt before hashing.

and more…

Table c: Passwords database for an application, which adds cryptographic salt to password before hashing.

and more………….…….

Observation and discussion.

From Table b, It can be observed that, when users use a similar password, their hashes will be the same (see the user with username erick). On the other hand, when a cryptographic salt is used (see Table c), users with a similar password  (see user kbruce) end up having different hashes.

To use the rainbow table, every hash in the password table is looked for in the rainbow table, and if found, it’s plain text is read in the left column. For instance, 9c0f64de05, which is in Table b, can be found in Table a. Thus, the password for kbruce in Table b is bac2019!

However, even though 9c0f64de05 in Table c can be found in the rainbow table (Table a), the password for kbruce in Table c can NEVER be bac2019! because there is salt (desa05) applied before hashing – a salt makes it impossible for an attacker to determine user passwords.

Instead of you scratching your head deciding which hashing algorithm to use and how to generate cryptographic salt, PHP has an easy way to hashing passwords and comparing hashes to plain text passwords – password_hash and password_verify.

How to use password_hash and password_verify.

password_hash() creates a new password hash using a strong one-way hashing algorithm and returns the hash value. password_hash() is compatible with crypt().

It generates the cryptographic salt under the hood.

To compare plain text password with the stored hash, we use password_verify ().


  • PHP, Apache Web server and MySQL/MariaDB, all bundled in XAMPP.
  • Set up, Postman.
  • Some knowledge of PHP’s PDO database interface. If you have never used PDO, read the article here.
  • A code editor of your choice, I love Visual Studio Code (VS Code).

How to go about it

Step 1:

Set up your project in xampp’s htdocs folder as shown below.

Project directory structure 

Step 2:

Create a database in MySQL database, say, article3, and run the following SQL query to create table user.

        full_name varchar (32) NOT NULL,
        username varchar (32) NOT NULL,
        password varchar (255),---Notice the password field size    

If you are using PostgreSQL, use the query below instead

       id serial PRIMARY KEY,
       full_name varchar (32) NOT NULL,
       username varchar (32) NOT NULL,
       password varchar (255),---Notice the password field size    

Step 3:

Insert this code in util.php file. The static variables will be accessed using the class Util and not an object

      class Util{
          //About DB 
          //your databae name here
          static $DB_NAME = "article3";
          //your database user here
          static $DB_USER = "root";
          //password for database user here
          static $DB_USER_PASS = "";
          //machine that is holding your database
          static $SERVER_NAME = "localhost";

Step 4:

Add the following code in the db.php. We are using PDO to connect to the database.

If you are using a PostgreSQL database, change the following line:

$dsn= "mysql:host=". Util::$SERVER_NAME . ";dbname=" . Util::$DB_NAME ."";


$dsn= "pgsql:host=". Util::$SERVER_NAME . ";dbname=" . Util::$DB_NAME ."";

Notice that we have only changed the database dialect from MySQL to pgsql but you will have to enable PDO_PGSQL driver for PostgreSQL database in php.ini file (see here).

Step 5:

Add the following code in the user.php file. In this class, we have a class User with two main methods register and login and three properties, username, password and fullName. Notice how we have used password_hash() in register function and password_verify() in login function.

step 6:

Add the following code in the index.php. This is the entry point of HTTP requests to our app.

Step 7:

Test your app using postman.

  1. User registration.

User registration

2. User login

User login

3. User login with the wrong password

User login with the wrong password

Link to PHP’s password hashing functions documentation


I hope you enjoyed reading and doing!

You May Also Like