Membuat Verifikasi Email Saat Registrasi Akun dengan Token & PHPMailer di PHP MySQL

By | 14 October 2025

Fitur verifikasi email saat registrasi akun memastikan bahwa pengguna benar-benar memiliki alamat email yang mereka daftarkan. Dengan sistem ini, akun baru tidak langsung aktif sampai pengguna mengklik link verifikasi yang dikirim ke email mereka.

Tujuannya:

  • Mencegah spam dan pendaftaran palsu,

  • Meningkatkan keamanan akun,

  • Menjaga kualitas database pengguna aktif.

Struktur Tabel Database

Tambahkan kolom verifikasi di tabel users.

ALTER TABLE users 
ADD COLUMN is_verified TINYINT(1) DEFAULT 0,
ADD COLUMN verify_token VARCHAR(100) DEFAULT NULL;

Kolom is_verified bernilai 0 = belum diverifikasi, 1 = sudah.
Kolom verify_token menyimpan token unik untuk konfirmasi email.

Proses Registrasi dengan Token Verifikasi

File: register.php

<?php
include 'config.php';
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = trim($_POST['username']);
    $email = trim($_POST['email']);
    $password = password_hash($_POST['password'], PASSWORD_BCRYPT);

    // Cek email sudah terdaftar
    $stmt = $conn->prepare("SELECT id FROM users WHERE email=?");
    $stmt->bind_param("s", $email);
    $stmt->execute();
    $stmt->store_result();

    if ($stmt->num_rows > 0) {
        echo "<p style='color:red'>Email sudah terdaftar.</p>";
    } else {
        // Buat token verifikasi
        $token = bin2hex(random_bytes(32));

        $stmt = $conn->prepare("INSERT INTO users (username, email, password, verify_token, is_verified) VALUES (?, ?, ?, ?, 0)");
        $stmt->bind_param("ssss", $username, $email, $password, $token);
        $stmt->execute();

        $verify_link = "https://yourdomain.com/verify_email.php?token=$token";

        // Kirim email dengan PHPMailer
        $mail = new PHPMailer(true);
        try {
            $mail->isSMTP();
            $mail->Host = 'smtp.yourhost.com';
            $mail->SMTPAuth = true;
            $mail->Username = 'no-reply@yourdomain.com';
            $mail->Password = 'yourpassword';
            $mail->SMTPSecure = 'tls';
            $mail->Port = 587;

            $mail->setFrom('no-reply@yourdomain.com', 'Support System');
            $mail->addAddress($email, $username);
            $mail->isHTML(true);
            $mail->Subject = 'Verifikasi Akun Anda';
            $mail->Body = "
                <h3>Halo $username,</h3>
                <p>Terima kasih telah mendaftar. Klik link berikut untuk verifikasi akun Anda:</p>
                <p><a href='$verify_link'>$verify_link</a></p>
                <p>Link ini hanya berlaku 24 jam.</p>
            ";
            $mail->send();

            echo "<p style='color:green'>Pendaftaran berhasil! Silakan cek email Anda untuk verifikasi akun.</p>";
        } catch (Exception $e) {
            echo "<p style='color:red'>Gagal mengirim email verifikasi. Error: {$mail->ErrorInfo}</p>";
        }
    }
}
?>

<form method="post">
    <label>Username:</label><br>
    <input type="text" name="username" required><br>
    <label>Email:</label><br>
    <input type="email" name="email" required><br>
    <label>Password:</label><br>
    <input type="password" name="password" required><br><br>
    <button type="submit">Daftar</button>
</form>

Halaman Verifikasi Email

File: verify_email.php

<?php
include 'config.php';

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

    $stmt = $conn->prepare("SELECT id FROM users WHERE verify_token=? AND is_verified=0");
    $stmt->bind_param("s", $token);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows > 0) {
        $user = $result->fetch_assoc();
        $id = $user['id'];

        // Update status verifikasi
        $stmt = $conn->prepare("UPDATE users SET is_verified=1, verify_token=NULL WHERE id=?");
        $stmt->bind_param("i", $id);
        $stmt->execute();

        echo "<p style='color:green'>Verifikasi berhasil! Akun Anda telah aktif. Silakan login.</p>";
    } else {
        echo "<p style='color:red'>Token tidak valid atau akun sudah terverifikasi.</p>";
    }
} else {
    echo "<p style='color:red'>Token tidak ditemukan.</p>";
}
?>

Cegah Login Sebelum Verifikasi

Pada login.php, tambahkan pengecekan kolom is_verified:

<?php
$stmt = $conn->prepare("SELECT id, password, is_verified FROM users WHERE email=?");
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    $user = $result->fetch_assoc();

    if ($user['is_verified'] == 0) {
        echo "<p style='color:red'>Akun Anda belum diverifikasi. Silakan cek email.</p>";
    } elseif (password_verify($password, $user['password'])) {
        $_SESSION['user_id'] = $user['id'];
        header("Location: dashboard.php");
        exit;
    } else {
        echo "<p style='color:red'>Password salah.</p>";
    }
} else {
    echo "<p style='color:red'>Email tidak ditemukan.</p>";
}
?>

Menangani Token Kadaluarsa (Opsional)

Untuk keamanan tambahan, kamu bisa menambahkan kolom verify_expires di tabel users dan menolak token yang sudah lewat waktu 24 jam.

ALTER TABLE users ADD COLUMN verify_expires DATETIME DEFAULT NULL;

Set saat registrasi:

<?php
$expires = date('Y-m-d H:i:s', strtotime('+1 day'));
$stmt = $conn->prepare("INSERT INTO users (username, email, password, verify_token, verify_expires) VALUES (?, ?, ?, ?, ?)");
$stmt->bind_param("sssss", $username, $email, $password, $token, $expires);
?>

Dan di verify_email.php, tambahkan pengecekan:

<?php
$stmt = $conn->prepare("SELECT id FROM users WHERE verify_token=? AND verify_expires > NOW()");
?>

Tips Keamanan & Praktik Terbaik

✅ Gunakan random_bytes() untuk membuat token unik.
✅ Gunakan PHPMailer dengan SMTP authentication (TLS/SSL).
✅ Simpan token di database dengan batas waktu kedaluwarsa.
✅ Hindari menampilkan token di halaman setelah diverifikasi.
✅ Gunakan HTTPS agar link verifikasi tidak bocor di URL.

Kesimpulan

Dengan sistem verifikasi email menggunakan PHPMailer dan token unik, kamu bisa:

  • Menyaring pengguna palsu,

  • Meningkatkan keamanan akun,

  • Menjaga reputasi domain email dari spam,

  • Menyediakan pengalaman registrasi profesional seperti platform besar.

Sistem ini juga siap diintegrasikan dengan:

  • Login multi-device (token remember me),

  • Reset password via email,

  • dan Session login aman.

Category: PHP