Tutorial Membuat OTP Sederhana dengan PHP

Tutorial106 Views

Sistem autentikasi berbasis OTP (One Time Password) semakin sering digunakan di berbagai aplikasi web maupun mobile. OTP berfungsi sebagai lapisan keamanan tambahan agar pengguna tidak hanya bergantung pada username dan password, tetapi juga pada kode unik yang hanya berlaku sekali dalam waktu tertentu. Dengan PHP, kita bisa membangun sistem OTP yang sederhana namun cukup kuat untuk kebutuhan login, verifikasi transaksi, hingga reset password.

Kenapa OTP Penting dalam Sistem Keamanan

OTP memberikan proteksi ekstra dari risiko pencurian password. Bayangkan jika data login pengguna bocor, peretas masih tidak bisa masuk tanpa kode OTP yang dikirim melalui SMS, email, atau aplikasi autentikasi. Karena sifatnya sekali pakai dan memiliki masa berlaku singkat, OTP membuat celah keamanan lebih kecil.

PHP sebagai bahasa server-side sangat fleksibel dalam membangun logika OTP. Kita bisa membuat kode acak, menyimpannya di database sementara, dan mengirimkannya ke pengguna lewat berbagai media.

Dasar-Dasar Membuat OTP di PHP

Sebelum membuat sistem OTP lengkap, kita perlu memahami dasar pembentukan kode. OTP biasanya berupa angka 4–8 digit, meski bisa juga berupa kombinasi huruf dan angka. PHP menyediakan fungsi bawaan untuk menghasilkan angka acak seperti rand() atau random_int().

Contoh sederhana membuat kode OTP 6 digit:

<?php
$otp = rand(100000, 999999);
echo "Kode OTP Anda: " . $otp;
?>

Namun, untuk alasan keamanan, sebaiknya gunakan random_int() karena lebih kriptografis:

<?php
$otp = random_int(100000, 999999);
echo "Kode OTP Aman: " . $otp;
?>

Kode di atas menghasilkan angka acak dengan tingkat keamanan yang lebih baik dibanding rand().

Menentukan Lama Berlaku OTP

OTP tidak boleh berlaku selamanya. Biasanya masa berlaku OTP antara 2–5 menit. Untuk itu, kita perlu menyimpan OTP bersama timestamp agar bisa melakukan validasi.

Misalnya, kita simpan OTP dalam database dengan waktu kedaluwarsa:

<?php
$otp = random_int(100000, 999999);
$expired_at = time() + (60 * 5); // Berlaku 5 menit

Di database, kita bisa menyimpan otp dan expired_at per user. Nantinya saat user memasukkan kode OTP, kita cek apakah masih valid.

Mengirim OTP ke Email

Salah satu cara populer untuk mengirim OTP adalah melalui email. PHP bisa memanfaatkan fungsi mail(), namun untuk aplikasi nyata lebih baik menggunakan library seperti PHPMailer.

Contoh sederhana:

<?php
$to = "user@example.com";
$subject = "Kode OTP Anda";
$message = "Kode OTP Anda adalah: $otp";
$headers = "From: no-reply@website.com";

mail($to, $subject, $message, $headers);
?>

Meskipun sederhana, cara ini kurang andal untuk aplikasi skala besar. Dengan PHPMailer, kita bisa mengirim email via SMTP agar lebih stabil.

Mengirim OTP ke Nomor Telepon

Untuk OTP berbasis SMS, kita biasanya butuh integrasi dengan API pihak ketiga, misalnya Twilio atau layanan lokal seperti Fonnte. PHP dapat mengirim request ke API tersebut menggunakan curl.

Contoh dasar:

<?php
$otp = random_int(100000, 999999);
$phone = "628123456789";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.smsprovider.com/send");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "number=$phone&message=Kode OTP: $otp");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>

Dengan integrasi seperti ini, OTP langsung masuk ke ponsel pengguna dan bisa dipakai untuk login atau transaksi.

Menyimpan dan Memvalidasi OTP di Database

Menghasilkan OTP saja tidak cukup, kita perlu mekanisme penyimpanan dan validasi. Misalnya menggunakan tabel user_otp:

CREATE TABLE user_otp (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    otp VARCHAR(6) NOT NULL,
    expired_at INT NOT NULL
);

Lalu ketika mengirim OTP:

<?php
$user_id = 1;
$otp = random_int(100000, 999999);
$expired_at = time() + (60 * 5);

// Simpan ke database
$stmt = $pdo->prepare("INSERT INTO user_otp (user_id, otp, expired_at) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $otp, $expired_at]);

Saat user memasukkan OTP:

<?php
$input_otp = $_POST['otp'];
$stmt = $pdo->prepare("SELECT otp, expired_at FROM user_otp WHERE user_id = ? ORDER BY id DESC LIMIT 1");
$stmt->execute([$user_id]);
$data = $stmt->fetch();

if ($data && $data['otp'] == $input_otp && time() <= $data['expired_at']) {
    echo "OTP valid!";
} else {
    echo "OTP salah atau kedaluwarsa!";
}
?>

Membatasi Percobaan OTP

Masalah lain adalah brute force, di mana penyerang mencoba menebak OTP dengan memasukkan banyak kombinasi. Untuk mencegahnya, kita perlu membatasi jumlah percobaan OTP per user.

Kita bisa menambahkan kolom attempt pada tabel OTP. Jika user salah memasukkan lebih dari 3 kali, OTP otomatis tidak valid lagi meskipun belum kedaluwarsa.

ALTER TABLE user_otp ADD COLUMN attempt INT DEFAULT 0;

Kemudian saat user salah memasukkan OTP:

<?php
$stmt = $pdo->prepare("UPDATE user_otp SET attempt = attempt + 1 WHERE user_id = ?");
$stmt->execute([$user_id]);

Jika attempt >= 3, sistem bisa memblokir validasi OTP tersebut.

Menggunakan OTP untuk Login Dua Faktor (2FA)

OTP sering dipakai dalam Two-Factor Authentication (2FA). Prosesnya biasanya seperti ini:

  1. User login dengan username dan password.
  2. Sistem mengirim OTP ke email atau SMS.
  3. User memasukkan OTP sebelum benar-benar masuk dashboard.

Skema ini membuat keamanan meningkat karena password saja tidak cukup untuk masuk.

OTP Berbasis Aplikasi Authenticator

Selain SMS dan email, OTP juga bisa dibuat berbasis aplikasi authenticator seperti Google Authenticator atau Authy. Tipe OTP ini disebut TOTP (Time-based One Time Password).

PHP bisa menggunakan library pihak ketiga seperti spomky-labs/otphp untuk menghasilkan dan memvalidasi TOTP. Dengan pendekatan ini, pengguna tidak bergantung pada SMS/email, melainkan aplikasi khusus yang lebih aman dari serangan phishing.

<?php
require 'vendor/autoload.php';
use OTPHP\TOTP;

$totp = TOTP::create();
$totp->setLabel('user@example.com');
echo "Secret: " . $totp->getSecret();
echo "Kode OTP: " . $totp->now();
?>

Kode di atas membuat OTP yang sinkron dengan aplikasi authenticator, sehingga lebih modern dan praktis.

Leave a Reply

Your email address will not be published. Required fields are marked *