Implementasi SMS Retriever API di Android
One Time Password (OTP) via SMS dapat mempermudah pengguna aplikasi dalam proses autentikasi. Secara garis besar, proses nya dapat dilihat dalam gambar berikut:
Dengan metode OTP via SMS, user cukup memasukkan nomor handphone, kemudian kode OTP akan dikirimkan ke user via SMS. Kode ini harus memiliki waktu expire (biasanya dalam hitungan menit atau jam) dan hanya bisa digunakan satu kali pakai saja. Untuk lebih detailnya dapat di lihat di white paper berikut OTP-Based Two-Factor Authentication Using Mobile Phones.
Pada tulisan ini saya akan membahas cara implementasi SMS Retriver API pada Android. Dengan menggunakan API ini, user tidak perlu dimintai permission READ_SMS dan RECEIVE_SMS.
Untuk bisa menggunakan API ini, kita user harus memiliki Play services versi 10.2 atau lebih baru. Dan di app nya sendiri perlu menambahkan package berikut:
// google play services
implementation "com.google.android.gms:play-services-gcm:16.0.0"
implementation "com.google.android.gms:play-services-auth:16.0.1"
Kemudian buat jalankan SMS retriever client:
val smsRetrieverClient = context
?.let { SmsRetriever.getClient(it) }
?: return
val smsRetrieverTask = smsRetrieverClient.startSmsRetriever()
Timber.d("SMS retriever has been started")
smsRetrieverTask.addOnSuccessListener {
Timber.d("smsRetrieverTask has been succeed")
}
smsRetrieverTask.addOnCanceledListener {
Timber.d("smsRetrieverTask has been cancelled")
}
Lalu tambahkan Broadcast Receiver untuk menerima SMS dengan OTP:
class SmsOtpReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == SmsRetriever.SMS_RETRIEVED_ACTION) {
val extras = intent.extras ?: return
val status = extras.get(SmsRetriever.EXTRA_STATUS) as Status
when (status.statusCode) {
CommonStatusCodes.SUCCESS -> {
val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
Timber.d("isi SMS dengan OTP: $message")
// Proses SMS disini
}
CommonStatusCodes.TIMEOUT -> {
Timber.e("Timeout, no message")
}
}
}
}
}
Dan jangan lupa untuk menambahkan Broadcast Receiver nya ke manifest:
<receiver android:name=".feature.auth.presentation.smsotp.SmsOtpReceiver" android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
Di sisi server kita juga harus menambah kan hash signature dari applikasi Android ke dalam pesan SMS nya serta mengubah format SMS seperti berikut:
<#> + Pesan SMS + app hash signature
Contoh:
<#> Kode OTP Anda adalah: AVB123
FA+9qCX9VSu
Untuk mendapatkan hash signature dari aplikasi Android, dapat menggunakan kode pada repo ini. Dan untuk versi Kotlin nya dapat di lihat disini.
Dengan kode di atas, kita bisa langsung dapat membaca SMS OTP tanpa perlu meminta access permission ke user. Untuk lebih detailnya dapat dilihat di dokumentasi Google Developer.