Cheap alternative to OTP SMS (MFA/2FA)

1k Views Asked by At

In my Android app, I need to link user's contacts to our DB user accounts, so the user can click on a specific contact and the app will translate it to our internal User ID (if exists), thus making communication easier and friendlier.

I thought about SMS OTP to verify the phone number (Phone Number -> Internal User ID) but it turns out to be extremely expensive (estimated 150k-300k new users each month). Our users are scattered all over the globe. The cost would be from $15k-$40k a month. Not something that we can afford.

Was looking also at fetching user's phone number from:

  • Google People API - requires special permissions and only gives out unverified "About Me" phone number.
  • Google Account API - not possible to fetch phone number
  • Google Sign In SSO - not possible to fetch phone number
  • Facebook Sign In SSO - not possible to fetch phone number (deprecated)
  • WhatsApp's AccountKit (OTP via WhatsApp) - deprecated
  • WhatsApp API - very expensive, similar if not more than SMS in some cases
  • Extracting from SIM - unreliable, mostly not working, not verified, can be faked

Are there any cheap alternatives to SMS OTP for fetching a verified phone number?

Thanks!

1

There are 1 best solutions below

3
On

There is a cheap hack (free) that you can use but it can be faked by the user, assuming the user has control of the typed phone number.

So you should use it only if you're comfortable with power users with ill-intentions working around it in some cases.

The idea here is that the cost of the SMS send will move to the user rather than your servers. A single SMS is free in most countries today, or very cheap in some of them, so a disclaimer such as "Carrier charges may apply" should cover you.

You'll need to implement the SMS Retriever API flow according to the tutorial but when it says to send an SMS from your server, you should instead have the user send that SMS from their own device:

Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse( "sms:" + inputNumber)); 
                    intent.putExtra( "sms_body", otpContents); 
                    startActivity(intent);

Or using SmsManager if your app has permission to send SMS.

The rest of the SMS Retriever flow should happen as in the tutorial, allowing your app to verify the user-input number was sent and received by the user.