PHP: Verifying a user via email.

This is a short guide on how to verify a recently-signed-up user via email. Typically, this kind of system is implemented whenever you want to make sure that the given email address belongs to the user that submitted it.

For the purpose of the example / tutorial, I am going to assume that you already know how to query a database with PHP (MySQL, PostgreSQL, MSSQL, Oracle, etc). If you don’t, then I’m sorry, but you’re running before you’ve learned how to walk.

The steps for verifying a user’s email address are actually pretty simple:

  1. As soon as the user signs up to your website, you should generate a random token for their account (there will be code examples below).
  2. This token should be stored in your database, against the user in question.
  3. Construct a URL / link that contains the token.
  4. Send this link out to the email address that the user provided when they registered with your website.
  5. If the user receives the email and clicks on the link in question, validate the token.
  6. If the token matches the token that you have in your database, mark the email address / account as being verified.

Firstly, lets look at how we can generate a token for the user:

<?php

//Get the unique user ID of the user that has just registered.

//Create a "unique" token.
$token = bin2hex(openssl_random_pseudo_bytes(16));

//Construct the URL.
$url = "http://example.com/verify.php?t=$token&user=$userId";

//Build the HTML for the link.
$link = '<a href="' . $url . '">' . $url . '</a>';

//Send the email containing the $link above.

The code above assumes that your website is at example.com and that your validation script is located at verify.php. Obviously, you should change this to suit your own setup.

When the user clicks on the link, they will be brought to verify.php, which will validate the token and user GET variables that are contained in the query string:

<?php

//Make sure that our query string parameters exist.
if(isset($_GET['token']) && isset($_GET['user'])){
    $token = trim($_GET['token']);
    $userId = trim($_GET['user']);
    
    $sql = "SELECT COUNT(*) AS num FROM users WHERE id = :user_id AND token = :token";
    $stmt = $pdo->prepare($sql);
    $stmt->bindParam(':user_id', $userId);
    $stmt->bindParam(':token', $token);
    $stmt->execute();
    
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    if($result['num'] == 1){
        //Token is valid. Verify the email address
    } else{
        //Token is not valid.
    }
    
}

As you can see, the theory behind it is actually pretty simple. Basically, we just verified that the token we received matched the token that was stored against the user’s account. In the example above, a few assumptions have been made (pointing these out in case people decide to copy and paste):

  • You are using the PDO extension to query MySQL. If this isn’t the case, then obviously you will need to modify the query above to suit your own needs.
  • Your user table is called users.
  • Your primary key is named id.
  • You are storing the token in a column called token.

How you actually mark the email address as being verified is up to you. You could store verified email addresses and the user accounts that they belong to in some kind of One-To-Many setup if you want. If you’re looking for a simple solution, then you could setup a TINYINT column in the users table called verified_email. This column would have a default value of 0, until the time comes when the user actually verifies their email address, in which case you would update the value of the column to 1.

Hopefully, this small guide was of use!