Dalam sistem verifikasi email berbasis token, banyak pengguna yang lupa atau terlambat melakukan konfirmasi. Akibatnya, token kadaluarsa dan proses verifikasi harus diulang dari awal. Hal ini tentu mengganggu pengalaman pengguna dan menambah beban server. Untuk mencegah hal tersebut, kamu dapat menambahkan fitur pengingat otomatis (email reminder) yang akan dikirim beberapa jam sebelum token verifikasi kedaluwarsa. Dengan pendekatan ini, pengguna akan diingatkan untuk segera mengonfirmasi email mereka sebelum waktu habis, menjaga sistem tetap efisien dan aman.
Artikel ini akan membahas langkah-langkah implementasi token expiry PHP yang dikombinasikan dengan sistem notifikasi otomatis menggunakan PHPMailer.
Konsep Sistem Peringatan Kadaluarsa Token
Sebelumnya, kita sudah memiliki tabel email_change_requests seperti berikut:
CREATE TABLE email_change_requests (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
new_email VARCHAR(255) NOT NULL,
token VARCHAR(100) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
expired_at DATETIME,
is_verified TINYINT(1) DEFAULT 0
);
Kali ini kita akan menambahkan sistem pengingat otomatis (reminder) yang dikirimkan beberapa jam sebelum expired_at.
Logika Reminder Otomatis
Misalnya, sistem akan mengirim pengingat 6 jam sebelum token kadaluarsa.
Berarti, kita perlu mencari token yang:
-
Belum diverifikasi (
is_verified = 0), dan -
Akan kadaluarsa dalam waktu ≤ 6 jam, tetapi belum lewat.
SQL Query-nya:
SELECT * FROM email_change_requests WHERE is_verified = 0 AND expired_at > NOW() AND TIMESTAMPDIFF(HOUR, NOW(), expired_at) <= 6;
Script PHP Reminder Token Expiry
Buat file PHP misalnya email_reminder_token.php:
<?php
require 'config.php';
require 'vendor/autoload.php'; // jika pakai composer PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$query = $conn->query("
SELECT r.*, u.email AS old_email
FROM email_change_requests r
JOIN users u ON r.user_id = u.id
WHERE r.is_verified = 0
AND r.expired_at > NOW()
AND TIMESTAMPDIFF(HOUR, NOW(), r.expired_at) <= 6
");
while ($row = $query->fetch_assoc()) {
$remaining = round((strtotime($row['expired_at']) - time()) / 3600, 1);
$token = $row['token'];
$verify_link = "https://yourwebsite.com/verify_email.php?token=$token";
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.yourmailserver.com';
$mail->SMTPAuth = true;
$mail->Username = 'no-reply@yourwebsite.com';
$mail->Password = 'password_email';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom('no-reply@yourwebsite.com', 'Your Website');
$mail->addAddress($row['new_email']);
$mail->isHTML(true);
$mail->Subject = '⚠️ Pengingat: Konfirmasi Email Sebelum Kadaluarsa';
$mail->Body = "
<h3>Halo!</h3>
<p>Anda telah mengajukan perubahan email ke <b>{$row['new_email']}</b>.</p>
<p>Namun, kami perhatikan Anda belum mengonfirmasi email ini.</p>
<p><b>Token Anda akan kedaluwarsa dalam sekitar $remaining jam.</b></p>
<p>Klik tautan berikut untuk menyelesaikan konfirmasi:</p>
<a href='$verify_link'>$verify_link</a>
<br><br>
<small>Jika Anda tidak meminta perubahan ini, abaikan pesan ini.</small>
";
$mail->send();
echo "Reminder dikirim ke {$row['new_email']}<br>";
} catch (Exception $e) {
echo "Gagal mengirim ke {$row['new_email']}: {$mail->ErrorInfo}<br>";
}
}
?>
Menjadwalkan Reminder dengan Cron Job
Agar sistem berjalan otomatis, buat cron job di server untuk menjalankan script di atas setiap 1 jam sekali:
0 * * * * /usr/bin/php /path/to/email_reminder_token.php
Artinya: script akan dijalankan setiap jam untuk mengecek token yang akan kedaluwarsa dalam 6 jam ke depan.
Mencegah Pengiriman Reminder Ganda
Agar tidak mengirim pengingat dua kali, kamu bisa menambahkan kolom baru reminder_sent pada tabel:
ALTER TABLE email_change_requests ADD COLUMN reminder_sent TINYINT(1) DEFAULT 0;
Lalu modifikasi query PHP menjadi:
$query = $conn->query("
SELECT r.*, u.email AS old_email
FROM email_change_requests r
JOIN users u ON r.user_id = u.id
WHERE r.is_verified = 0
AND r.reminder_sent = 0
AND expired_at > NOW()
AND TIMESTAMPDIFF(HOUR, NOW(), expired_at) <= 6
");
Setelah berhasil mengirim email, update status reminder_sent:
$update = $conn->prepare("UPDATE email_change_requests SET reminder_sent = 1 WHERE id = ?");
$update->bind_param("i", $row['id']);
$update->execute();
Pesan Pengingat di Dashboard User
Kamu juga bisa menampilkan pesan peringatan di halaman profil jika email baru masih belum dikonfirmasi dan mendekati kadaluarsa:
$user_id = $_SESSION['user_id'];
$stmt = $conn->prepare("
SELECT new_email, expired_at
FROM email_change_requests
WHERE user_id = ? AND is_verified = 0
");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
$remaining = round((strtotime($row['expired_at']) - time()) / 3600, 1);
if ($remaining <= 6) {
echo "<div class='alert alert-warning'>
Email baru <b>{$row['new_email']}</b> belum dikonfirmasi.
Sisa waktu konfirmasi: <b>$remaining jam lagi</b>.
</div>";
}
}
Kesimpulan
Dengan menambahkan sistem email reminder otomatis sebelum token expiry di PHP, kamu tidak hanya meningkatkan keamanan akun, tetapi juga memperbaiki pengalaman pengguna. Fitur ini membantu mengingatkan pengguna agar segera menyelesaikan verifikasi email sebelum batas waktu habis, sehingga sistem tetap bersih, efisien, dan profesional.
Langkah berikutnya kamu bisa menggabungkan fitur ini dengan dashboard manajemen keamanan akun, agar pengguna bisa melihat semua notifikasi dan log aktivitas login dalam satu tempat.