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.