Buat kode dengan entropi nyata
Gunakan generator acak yang aman secara kriptografis, jangan pernah seed yang dapat ditebak atau nilai turunan cap waktu. Enam digit adalah keseimbangan umum antara keamanan dan kegunaan; kode lebih pendek butuh pembatasan laju lebih ketat agar tetap aman.
Jangan pernah kirim kode yang sama dua kali, dan jangan buat kode dapat ditebak dari id pengguna atau urutan. Seluruh keamanan OTP SMS bertumpu pada kode yang tidak dapat diprediksi dalam masa hidupnya yang singkat.
- Gunakan CSPRNG (mis. pustaka secrets/crypto), bukan PRNG serba guna.
- 6 digit adalah standar; jika Anda memakai 4, perketat pembatasan laju dan kedaluwarsa.
- Satu kode per permintaan; batalkan kode sebelumnya saat menerbitkan yang baru.
Simpan kode dengan aman, jangan pernah teks biasa
Perlakukan OTP seperti kata sandi berumur pendek. Simpan hash dari kode (dengan pengidentifikasi dan kedaluwarsa) alih-alih nilai mentah, sehingga kebocoran basis data tidak mengungkap kode aktif. Bandingkan memakai fungsi waktu konstan untuk menghindari serangan waktu, dan hapus catatan begitu dipakai atau kedaluwarsa.
- Hash kode sebelum menyimpan; bandingkan dalam waktu konstan.
- Ikat tiap kode ke satu pengguna/sesi dan tujuan.
- Hapus saat berhasil, kedaluwarsa, atau setelah batas percobaan tercapai.
Tetapkan jendela kedaluwarsa singkat
Kode harus hidup dalam hitungan menit, bukan jam. Kedaluwarsa 5โ10 menit adalah rentang umum: cukup panjang agar SMS yang tertunda masih sampai, cukup pendek sehingga kode yang bocor biasanya sudah mati. Tampilkan sisa masa berlaku kepada pengguna agar pesan yang lambat tidak terbaca sebagai alur yang rusak.
Pasangkan kedaluwarsa singkat dengan jeda kirim ulang, atau pengguna akan menekan kirim ulang saat pesan tertunda dan melipatgandakan biaya SMS Anda.
Batasi laju di setiap dimensi
Pembatasan laju adalah yang menghentikan tebakan brute-force atas kode maupun penyalahgunaan endpoint kirim Anda (yang menghabiskan uang dan bisa membuat pengirim Anda ditandai). Batasi per nomor telepon, per IP, dan per akun, baik pada pengiriman maupun verifikasi.
- Percobaan verifikasi: batasi percobaan per kode (mis. 5) lalu batalkan dan paksa kirim ulang.
- Permintaan kirim: jeda antar-kirim dan batas harian per nomor.
- Penjaga global: batas per IP dan per akun untuk menumpulkan penyalahgunaan otomatis.
- Tambahkan backoff eksponensial atau CAPTCHA saat batas berulang kali tersentuh.
Tangani coba ulang dan kanal fallback
SMS bersifat upaya terbaik, jadi alur yang baik mengasumsikan sebagian pesan tidak akan sampai. Tawarkan kirim ulang setelah jeda, dan setelah satu atau dua percobaan SMS gagal, tingkatkan ke kanal fallback โ panggilan suara yang membacakan kode, WhatsApp, atau email โ yang persis diotomatiskan oleh Verify API terkelola.
Buat keadaan gagal terasa manusiawi: jalur "tidak menerimanya?" yang jelas, cara mengganti nomor, dan kontak dukungan setelah kegagalan berulang.
- 1
Percobaan pertama: SMS
Kirim kode dan mulai hitung mundur yang terlihat dengan jeda kirim ulang.
- 2
Kirim ulang atas permintaan
Izinkan kirim ulang setelah jeda; batalkan kode sebelumnya saat menerbitkan yang baru.
- 3
Tingkatkan kanal
Setelah kegagalan SMS berulang, tawarkan suara atau kanal alternatif untuk mengirim verifikasi yang sama.
- 4
Tawarkan jalan keluar
Biarkan pengguna memperbaiki nomornya atau menghubungi dukungan alih-alih buntu.
Tingkatkan UX tanpa melemahkan keamanan
Sentuhan kecil menaikkan tingkat penyelesaian: gunakan WebOTP API dan format isi-otomatis SMS agar peramban seluler dapat membaca kode, jaga kata-kata pesan tetap konsisten (sebagian platform menyimpan pengirim tepercaya), dan jangan sertakan apa pun selain kode dan nama aplikasi Anda. Hindari tautan dalam pesan OTP โ itu membiasakan pengguna mengeklik dan memicu filter spam operator.
- Dukung WebOTP / isi-otomatis kode sekali pakai di seluler.
- Jaga pesan tetap minimal: nama aplikasi + kode, tanpa pemasaran, tanpa tautan.
- Lokalkan teks pesan tetapi jaga format kode tetap stabil.