How to verify email with a verification code - PHP & MySQL

How to verify email with a verification code – PHP & MySQL

When someone registers in your website, send him/her an email with a verification code and show a form to enter the code in your website. User must enter the verification code in that form to verify his email. Only verified users will be allowed to login.

Create users table

First you need to create a users table in your database. Your table must have “verification_code” field that will hold the code sent in email. And the “email_verified_at” field that tells the time the email was verified. This field will also be used to check if the user has verified his email or not.

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` text NOT NULL,
  `email` text NOT NULL,
  `password` text NOT NULL,
  `verification_code` text NOT NULL,
  `email_verified_at` datetime DEFAULT NULL
);

User registration

Usually registration form has a name, email and a password field for user.

<form method="POST">
    <input type="text" name="name" placeholder="Enter name" required />
    <input type="email" name="email" placeholder="Enter email" required />
    <input type="password" name="password" placeholder="Enter password" required />

    <input type="submit" name="register" value="Register">
</form>

When this form submits, we need to generate a verification code and send it to user. To send an email, we are going to use a library called “PHPMailer”. Make sure you have “composer” downloaded and installed in your system. Run the following command at the root of your project:

composer require phpmailer/phpmailer

Following code will send a verification code to the user’s email address and save the user’s data in database:

<?php
    //Import PHPMailer classes into the global namespace
    //These must be at the top of your script, not inside a function
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;

    //Load Composer's autoloader
    require 'vendor/autoload.php';

    if (isset($_POST["register"]))
    {
        $name = $_POST["name"];
        $email = $_POST["email"];
        $password = $_POST["password"];

        //Instantiation and passing `true` enables exceptions
        $mail = new PHPMailer(true);

        try {
            //Enable verbose debug output
            $mail->SMTPDebug = 0;//SMTP::DEBUG_SERVER;

            //Send using SMTP
            $mail->isSMTP();

            //Set the SMTP server to send through
            $mail->Host = 'smtp.gmail.com';

            //Enable SMTP authentication
            $mail->SMTPAuth = true;

            //SMTP username
            $mail->Username = 'your_email@gmail.com';

            //SMTP password
            $mail->Password = 'your_password';

            //Enable TLS encryption;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;

            //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
            $mail->Port = 587;

            //Recipients
            $mail->setFrom('your_email@gmail.com', 'your_website_name');

            //Add a recipient
            $mail->addAddress($email, $name);

            //Set email format to HTML
            $mail->isHTML(true);

            $verification_code = substr(number_format(time() * rand(), 0, '', ''), 0, 6);

            $mail->Subject = 'Email verification';
            $mail->Body    = '<p>Your verification code is: <b style="font-size: 30px;">' . $verification_code . '</b></p>';

            $mail->send();
            // echo 'Message has been sent';

            $encrypted_password = password_hash($password, PASSWORD_DEFAULT);

            // connect with database
            $conn = mysqli_connect("localhost:8889", "root", "root", "test");

            // insert in users table
            $sql = "INSERT INTO users(name, email, password, verification_code, email_verified_at) VALUES ('" . $name . "', '" . $email . "', '" . $encrypted_password . "', '" . $verification_code . "', NULL)";
            mysqli_query($conn, $sql);

            header("Location: email-verification.php?email=" . $email);
            exit();
        } catch (Exception $e) {
            echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
        }
    }
?>

User login

When user try to login, we must check if the user’s email is verified or not. Usually login form has 2 fields, email and password:

<form method="POST">
    <input type="email" name="email" placeholder="Enter email" required />
    <input type="password" name="password" placeholder="Enter password" required />

    <input type="submit" name="login" value="Login">
</form>

When this form submits, we will check if the user’s credentials are okay. And also if his/her email is verified.

<?php
    
    if (isset($_POST["login"]))
    {
        $email = $_POST["email"];
        $password = $_POST["password"];

        // connect with database
        $conn = mysqli_connect("localhost:8889", "root", "root", "test");

        // check if credentials are okay, and email is verified
        $sql = "SELECT * FROM users WHERE email = '" . $email . "'";
        $result = mysqli_query($conn, $sql);

        if (mysqli_num_rows($result) == 0)
        {
            die("Email not found.");
        }

        $user = mysqli_fetch_object($result);

        if (!password_verify($password, $user->password))
        {
            die("Password is not correct");
        }

        if ($user->email_verified_at == null)
        {
            die("Please verify your email <a href='email-verification.php?email=" . $email . "'>from here</a>");
        }

        echo "<p>Your login logic here</p>";
        exit();
    }
?>

Email verification

Create a file named “email-verification.php” and create a hidden input field for email and a text field for verification code:

<form method="POST">
    <input type="hidden" name="email" value="<?php echo $_GET['email']; ?>" required>
    <input type="text" name="verification_code" placeholder="Enter verification code" required />

    <input type="submit" name="verify_email" value="Verify Email">
</form>

When this form submits, we will check if the verification code matches with the one in database. If the code does not match then it will show an error, otherwise it will mark the user as verified.

<?php

    if (isset($_POST["verify_email"]))
    {
        $email = $_POST["email"];
        $verification_code = $_POST["verification_code"];

        // connect with database
        $conn = mysqli_connect("localhost:8889", "root", "root", "test");

        // mark email as verified
        $sql = "UPDATE users SET email_verified_at = NOW() WHERE email = '" . $email . "' AND verification_code = '" . $verification_code . "'";
        $result  = mysqli_query($conn, $sql);

        if (mysqli_affected_rows($conn) == 0)
        {
            die("Verification code failed.");
        }

        echo "<p>You can login now.</p>";
        exit();
    }

?>

Conclusion

Adding this feature to your website helps you to separate real and fake email addresses in your database. It will greatly help you in your marketing and you will be satisfied that your emails are going to real email accounts. If you want to know if your email is being read by the receiver or not, please follow this.

Leave a Reply

Please disable your adblocker or whitelist this site!