Membuat Fitur Ganti Email dengan Verifikasi Token & PHPMailer di PHP MySQL

By | 14 October 2025

Setiap sistem akun modern seperti Google, Facebook, dan Shopee selalu menyediakan fitur “Ganti Email”. Tapi mengganti email tidak boleh sembarangan karena email adalah identitas utama akun dan digunakan untuk login, reset password, serta notifikasi penting. Untuk itu dalam artikel kali ini akan dibahas cara membuat fitur ganti email dengan verifikasi token yang dikirim ke email dengan PHPMailer di PHP MySql.

Fitur ini harus:

  1. Mengirim token verifikasi ke email baru,

  2. Memastikan hanya pemilik sah yang bisa mengonfirmasi,

  3. Mencegah perubahan tanpa izin atau eksploitasi.

Struktur Database

Tambahkan dua kolom baru di tabel users yang sudah dibuat sebelumnya:

ALTER TABLE users 
ADD COLUMN new_email VARCHAR(100) DEFAULT NULL,
ADD COLUMN email_token VARCHAR(100) DEFAULT NULL;

Fungsinya:

  • new_email → Menyimpan alamat email baru sementara sebelum diverifikasi.

  • email_token → Token acak yang dikirim ke email baru untuk konfirmasi.

Form Ganti Email

Buat file change_email.php:

<?php
session_start();
include 'config.php';

if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit;
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $user_id = $_SESSION['user_id'];
    $new_email = trim($_POST['new_email']);

    // Cek apakah email baru sudah dipakai
    $check = $conn->prepare("SELECT id FROM users WHERE email = ?");
    $check->bind_param("s", $new_email);
    $check->execute();
    $check->store_result();

    if ($check->num_rows > 0) {
        $message = "<div class='alert alert-danger'>Email sudah terdaftar!</div>";
    } else {
        $token = bin2hex(random_bytes(32));

        $stmt = $conn->prepare("UPDATE users SET new_email=?, email_token=? WHERE id=?");
        $stmt->bind_param("ssi", $new_email, $token, $user_id);
        $stmt->execute();

        // Kirim email verifikasi ke email baru
        include 'send_email_verification.php';
        sendVerificationEmail($new_email, $token);

        $message = "<div class='alert alert-info'>Tautan verifikasi telah dikirim ke $new_email.</div>";
    }
}
?>

<h3>Ganti Email Akun</h3>
<?= $message ?? '' ?>
<form method="post">
    <label>Email Baru:</label>
    <input type="email" name="new_email" required class="form-control">
    <button type="submit" class="btn btn-primary mt-2">Kirim Verifikasi</button>
</form>

Mengirim Email Verifikasi dengan PHPMailer

Buat file send_email_verification.php:

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

function sendVerificationEmail($toEmail, $token) {
    $verifyLink = "https://yourdomain.com/verify_new_email.php?token=$token";

    $mail = new PHPMailer(true);
    try {
        $mail->isSMTP();
        $mail->Host = 'smtp.yourdomain.com';
        $mail->SMTPAuth = true;
        $mail->Username = 'noreply@yourdomain.com';
        $mail->Password = 'yourpassword';
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;

        $mail->setFrom('noreply@yourdomain.com', 'Keamanan Akun');
        $mail->addAddress($toEmail);

        $mail->isHTML(true);
        $mail->Subject = 'Verifikasi Email Baru Akun Anda';
        $mail->Body = "
        <h2>Verifikasi Perubahan Email</h2>
        <p>Kami menerima permintaan untuk mengganti email akun Anda menjadi:</p>
        <p><b>$toEmail</b></p>
        <p>Silakan klik tombol di bawah ini untuk mengonfirmasi:</p>
        <p><a href='$verifyLink' style='background:#007BFF;color:#fff;padding:10px 15px;text-decoration:none;border-radius:5px;'>Verifikasi Email Baru</a></p>
        <p>Jika Anda tidak meminta perubahan ini, abaikan pesan ini.</p>";

        $mail->send();
    } catch (Exception $e) {
        error_log("Gagal mengirim email: {$mail->ErrorInfo}");
    }
}
?>

Halaman Verifikasi Email Baru

Buat file verify_new_email.php:

<?php
include 'config.php';

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

    $stmt = $conn->prepare("SELECT id, new_email FROM users WHERE email_token=? AND new_email IS NOT NULL");
    $stmt->bind_param("s", $token);
    $stmt->execute();
    $result = $stmt->get_result();

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

        $update = $conn->prepare("UPDATE users SET email=?, new_email=NULL, email_token=NULL WHERE id=?");
        $update->bind_param("si", $user['new_email'], $user['id']);
        $update->execute();

        echo "<div class='alert alert-success'>Email berhasil diganti!</div>";
    } else {
        echo "<div class='alert alert-danger'>Token tidak valid atau sudah digunakan.</div>";
    }
}
?>

Alur Kerja Fitur Ganti Email

  1. Pengguna login ke akun.

  2. Masuk ke halaman Ganti Email.

  3. Isi alamat email baru → sistem kirim email berisi link verifikasi.

  4. Pengguna buka email baru dan klik tautan verifikasi.

  5. Sistem memperbarui email lama → email baru resmi digunakan.

Keamanan Tambahan yang Direkomendasikan

Pastikan user login ulang sebelum mengganti email (re-authentication).

Batasi jumlah permintaan ganti email (misalnya 3 kali per hari).

Token verifikasi kadaluarsa (misalnya 1 jam setelah dikirim).
Tambahkan kolom email_token_expire untuk ini:

ALTER TABLE users ADD COLUMN email_token_expire DATETIME DEFAULT NULL;

Kirim notifikasi ke email lama bahwa email telah diganti (antispoofing).

Kirim Notifikasi ke Email Lama (Opsional)

Tambahkan fungsi berikut setelah email baru terverifikasi:

<?php
function notifyOldEmail($oldEmail, $newEmail) {
    $mail = new PHPMailer(true);
    $mail->setFrom('noreply@yourdomain.com', 'Keamanan Akun');
    $mail->addAddress($oldEmail);
    $mail->Subject = "Perubahan Email Akun Anda";
    $mail->Body = "Email akun Anda telah diubah menjadi: $newEmail. Jika ini bukan Anda, segera hubungi tim dukungan kami.";
    $mail->send();
}
?>

Kesimpulan

Dengan sistem Ganti Email dengan Verifikasi Token, kamu sudah menambahkan lapisan keamanan penting ke dalam aplikasi PHP kamu.
Sistem ini:
✅ Memastikan hanya pemilik sah yang bisa mengganti email
✅ Mengirim link verifikasi ke email baru
✅ Mencegah pengambilalihan akun lewat perubahan email

Category: PHP