Site icon Mailtrap

How to Set up Email Verification in PHP via a Verification Token: Complete Guide

This is a graphic representation of PHP email verification for an article that covers the topic in detail.

Email verification is the process of ensuring an email address exists and can receive emails. Whereas, email validation checks if the address is properly formatted; that is – written according to specific standards (e.g. UTF-8). 

In this article, I’ll talk about PHP email verification and how to use it for web development and user authentication via a verification token. The article involves a few micro tutorials, including:

So, let’s get to it. 

Setting up email sending

To send verification emails, you can use PHP’s built-in mail() function or a library like PHPMailer, which offers more features and better reliability.

Since I want to make the tutorial as safe and production-ready as possible, I’ll be using ‘PHPMailer’. Check the code to install PHPMailer via Composer:

composer require phpmailer/phpmailer

As for the sending itself, I’ll be using Mailtrap API/SMTP, the SMTP method. 

Why use Mailtrap API/SMTP?

It’s an email delivery platform to test, send, and control your emails in one place. And, among other things, you get the following:

All that allows you to bootstrap the email verification process, and keep it safe and stable for all. 

Moving on to the settings to configure PHPMailer with Mailtrap:

$phpmailer = new PHPMailer();
$phpmailer->isSMTP();
$phpmailer->Host = 'live.smtp.mailtrap.io';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 587;
$phpmailer->Username = 'api';
$phpmailer->Password = 'YOUR_MAILTRAP_PASSWORD';

Here’s the PHPMailer setup:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

function sendVerificationEmail($email, $verificationCode) {
    $mail = new PHPMailer(true);

    try {
        // Server settings
        $mail->isSMTP();
        $mail->Host = 'live.smtp.mailtrap.io';
        $mail->SMTPAuth = true;
        $mail->Username = 'api';
        $mail->Password = 'YOUR_MAILTRAP_PASSWORD';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;

        // Recipients
        $mail->setFrom('youremail@example.com', 'Your Website');
        $mail->addAddress($email);

        // Content
        $mail->isHTML(false);
        $mail->Subject = 'Email Verification';
        $mail->Body    = "Your verification code is: $verificationCode";

        $mail->send();
        return true;
    } catch (Exception $e) {
        return false;
    }
}

Note that the code above doesn’t send the verification token (click here to jump to the code snippet with the verification token). It’s only an example of how to set up Mailtrap SMTP and define the verification function. Here’s a quick breakdown of key points:

Tips: 

Creating a registration form

The below is a simple registration form, it contains the header and user account information (username, email, and password). 

It doesn’t have any CSS stylesheet or div class since this is only an example. 

However, I’d advise you to include these on production and align them with the design language of your brand. Otherwise, your form may look unprofessional and users would be reluctant to engage with it. 

<!DOCTYPE html>
<html>
<head>
    <title>Register</title>
</head>
<body>
    <form action="register.php" method="post">
        <label>Username:</label>
        <input type="text" name="username" required>
        <br>
        <label>Email:</label>
        <input type="email" name="email" required>
        <br>
        <label>Password:</label>
        <input type="password" name="password" required>
        <br>
        <input type="submit" name="register" value="Register">
    </form>
</body>
</html>

Bonus Pro TipConsider using JavaScript with your forms 

If you want a full tutorial on how to create a PHP contact form that includes reCaptcha, check the video below ⬇️. 

Now, I’ll move to email address verification.  

Email address verification

Here’s a simple script to check for the domain and the MX record. It basically allows you to verify email by performing an MX lookup.

<?php

// This method checks if the domain part of the email address has a functioning mail server.

$email = "user@example.com";

list($user, $domain) = explode(separator:"@", $email)

if (filter_var($email, filter:FILTER_VALIDATE_EMAIL) && getmxrr($domain, &hosts: $mxhosts)){
    echo "Valid email address with a valid mail server" . PHP_EOL;
} else {
    echo "Invalid email address or no valid mail server found" . PHP_EOL;
}

However, the script doesn’t send email for user activation and authentication. Also, it doesn’t store any data in MySQL. 

For that, I’ll do the following in the next sections: 

Tip: Similar logic can be applied to a logout/login form. 

Generating verification token

A verification token is a unique string generated for each user during registration. This token is included in the verification email and there are two methods to generate it.

Method 1

The first method leverages the bin2hex command to create a random token with the parameter set to (random_bytes(50))

$token = bin2hex(random_bytes(50));

Method 2

Alternatively, you can generate the token with the script below. And I’ll be using that script in the email-sending script.

<?php
function generateVerificationCode($length = 6) {
    $characters = '0123456789';
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $code;
}
?>

Storing verification token

Before sending the verification email, it’s vital to ensure you properly handle and store user data. I’ll use a simple SQL schema to create the users table and store the generated token in the database along with the user’s registration information.

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    token VARCHAR(255) DEFAULT NULL,
    is_verified TINYINT(1) DEFAULT 0
);

Quick breakdown: 

The script above creates a users table with the following columns:

Sending verification token 

Overall, the script below is amalgamation of everything previously discussed in the article and it’s designed to: 

Note that the script is geared towards Mailtrap users and it leverages the SMTP method. 

<?php

require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP
use PHPMailer\PHPMailer\Exception;

//Function to generate a random verification code
1 usage
function generateVerificationCode($length = 6) {
    $characters = '0123456789';
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $code;
}

// Function to send a verification email using PHPMailer
1 usage
function sendVerificationEmail($email, $verificationCode) {
    $mail = new PHPMailer (exception: true);

    try {
        // Server settings
        $mail ->SMTPDebug = SMTP::DEBUG_OFF; // Set to DEBUG_SERVER for debugging
        $mail ->isSMTP();
        $mail ->Host = 'live.smtp.mailtrap.io'; // Mailtrap SMTP server host 
        $mail ->SMTPAuth = true;
        $mail ->Username = 'api'; // Your Mailtrap SMTP username
        $mail ->Password = 'YOUR_MAILTRAP_PASSWORD'; // Your Mailtrap SMTP password
        $mail ->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
        $email ->Port = 587; // TCP port to connect to

        //Recipients
        $mail->setFrom(address:'mailtrapclub@gmail.com', name:"John Doe"); //Sender's email and name
        $mail->addAddress($email); // Recipient's email

        //Content
        $mail->isHTML(isHTML:false); //Set to true if sending HTML email
        $mail->Subject = 'Email Verification';
        $mail->Body = "Your verification code is: $verificationCode";

        $mail->send();
        return true;
    }catch (Exception $e) {
        return false;
    }
}

//Example usage
$email = "mailtrapclub+test@gmail.com"
$verificationCode = generateVerificationCode();

if (sendVerificationEmail($email,$verificationCode)){
    echo "A verification email has been sent to $email. Please check your inbox and enter the code to verrify your email." . PHP_EOL;
} else {
    echo "Failed to send the verification email. Please try again later." . PHP_EOL;
}

Verifying verification token

Yeah, the title is a bit circular, but that’s exactly what you need. The script below enables the “verification of verification” flow 😀 that moves like this: 

  1. A user hits the verification link. 
  2. The token gets validated.
  3. The user’s email is marked as verified in the database. 
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "user_verification";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

if (isset($_GET['token'])) {
    $token = $_GET['token'];

    $stmt = $conn->prepare("SELECT * FROM users WHERE token=? LIMIT 1");    $stmt->bind_param("s", $token);    $stmt->execute();
    $result = $stmt->get_result();
    if ($result->num_rows > 0) {
        $user = $result->fetch_assoc();        $stmt->close();
        $stmt = $conn->prepare("UPDATE users SET is_verified=1, token=NULL WHERE id=?");        $stmt->bind_param("i", $user['id']);

        if ($stmt->execute() === TRUE) {
            echo "Email verification successful!";
        } else {
            echo "Error: " . $conn->error;
        }        $stmt->close();
    } else {
        echo "Invalid token!";
    }
}

$conn->close();
?>

Email verification as a part of email testing

I wouldn’t recommend sending verification emails before thoroughly testing them in a sandbox environment. These emails are a key part of a new user onboarding process, and you need to be sure they look and perform as they’re supposed to. 

The main things to check are that:

To do this, I’ll be using Mailtrap Email Testing

Mailrap Email Testing is an email sandbox to inspect and debug emails in staging, dev, and QA environments before sending them to recipients. Notable features include:

The PHPMailer configuration to set up testing is as follows:

$phpmailer = new PHPMailer();
$phpmailer->isSMTP();
$phpmailer->Host = 'sandbox.smtp.mailtrap.io';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 2525;
$phpmailer->Username = 'Your_Mailtrap_Username';
$phpmailer->Password = 'Your_Mailtrap_Password';

Note: To test, you can only refactor the PHP email verification code to use testing credentials, and run it. 

If you want to learn more about PHP testing with different frameworks, check this article

Wrapping up

I’ve walked through PHP email verification and the use of the verification token. We’ve covered everything from setting up the environment, to sending and verifying emails. 

Following these steps will help you ensure the authenticity of your users and maintain a clean and secure user database.

Happy verification!

Exit mobile version