Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to verify user's mobile number using Firebase

I know that I can use Firebase's phone verification on Android and iOS, but the problem is that the information about client's verification can easily be forged on the client side, because I using only server side SSL certificate, so, only client knows that the server is trusted.

So, I decided to send mobile number on the server-side and check it there: send verification code and ask this verification code from the user. But I can't see any C++ server Firebase SDK, only client-side C++ SDK is available. So, I have two options:

  • Understand how is client-side verification can be trusted on the server-side(note that I can have untrusted clients)? So, it's means I could use main Firebase phone number auth method.
  • Use server-side phone verification.

Please, help me with this misunderstanding in the Firebase.

like image 548
konstantin_doncov Avatar asked Jul 20 '17 21:07

konstantin_doncov


1 Answers

Client side absolutely works here. The flow is like this:

  1. You request a sign in using a phone number
  2. The Firebase Phone Auth server sends a code to that number
  3. The user enters your code into your app, which sends it to the Firebase Auth server
  4. The Firebase Auth server returns you a Firebase Auth token

This works because a malicious user could only know the code if they had your phone. It doesn't guarantee the device is the one with that phone number (the user could have two phones, or sign in with a phone on a laptop), but it does verify the user has access to that number.

For verifying that to your own backend, you retrieve a Firebase ID token. This is just a little bundle of base64 encoded JSON, but importantly its cryptographically signed by Firebase. This means on your server you can verify that it was really created by Firebase, for the user and phone number that is contained within it. A user couldn't generate one of those tokens without access to the underlying account.

See the docs on verifying ID tokens for more!

So your next steps would be:

Retrieve the Firebase ID token

You can do this any time you're signed in.

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
   mUser.getToken(true)
    .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
        public void onComplete(@NonNull Task<GetTokenResult> task) {
            if (task.isSuccessful()) {
                String idToken = task.getResult().getToken();
                // Send token to your backend via HTTPS
                // ...
            } else {
                // Handle error -> task.getException();
            }
        }
    });

Verify on server the contents of the ID token.

The admin SDKs are set up out of the box to check for the right certificate, audience, expiry, and other important properties of an ID token.

admin.auth().verifyIdToken(idToken)
  .then(function(decodedToken) {
    var uid = decodedToken.uid;
    // ...
  }).catch(function(error) {
    // Handle error
  });

decodedToken will contain properties for the phone number too!

like image 114
Ian Barber Avatar answered Sep 17 '22 14:09

Ian Barber