Improve Your Multifactor Auth With Vonage APIs and Firebase
Published on September 5, 2024

Introduction 

In this blog post, I’ll show you how to improve your multifactor authentication using our Vonage SIM Swap and Verify APIs. We also use Firebase Services to store our functions with Cloud Functions, data in the Cloud Firestore database, and our web app using Firebase hosting.

The application's source code can be found on our GitHub repo.

Note: This blog post adds Firebase Services to the existing blog post Improve Your Multifactor Auth With Verify and SIM Swap APIs. The tutorial covers both creating the server using Express and in the cloud. You can check this previous blog post and the GitHub repo for in-depth explanations.

Prerequisites

  • A Vonage developer account

  • Node.js and npm are installed on your machine

  • A Firebase project is set up in the Firebase Console (I’ve named mine account-recovery-demo)

  • Firebase CLI installed

  •  A code/text editor

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Overview Diagram and Application Architecture

This account recovery tutorial shows how users can log in, reset passwords, or verify their identity by accessing the web front-end page. This page interacts with the Firebase Functions back-end, storing and retrieving user credentials from Firebase Cloud Firestore.

Once the user tries resetting their password, they will receive a Verification One-time Code generated using the Vonage Verify API. However, that will only happen once the SIM Swap details are checked with the Communication Service providers using the Vonage SIM Swap API.

The application follows a client-server architecture. The client handles user interactions through HTML and JavaScript, including entering phone numbers and submitting verification codes. The client and the server communicate via GET / POST requests.   The server, developed in Node.js with Express, manages backend logic, including interfacing with Vonage’s SIM Swap and Verify v2 APIs for security checks and authentication.   Firebase Hosting serves the web application, Firebase Functions handle server-side logic, and Firestore stores user data and verification status.Overview Diagram

The application follows a client-server architecture. The client handles user interactions through HTML and JavaScript, including entering phone numbers and submitting verification codes. Firebase Hosting serves the web application, Firebase Functions handle server-side logic, and Firestore stores user data and verification status.

How to Set Up a Cloud Functions Project

Previously, the Express app managed routes and API calls directly within a server environment. Using Firebase Cloud Functions, each endpoint previously defined in the Express app is mapped to a specific cloud function by rewriting the rules in the firebase.json file. This setup decouples the routing mechanism from the application logic, allowing each function to be independently scaled and managed. Firebase automatically handles incoming requests and directs them to the appropriate cloud function based on the rewrite rules, such as sendcode to sendCode or /login to login. Since the web client now resides in a domain different from the server, we are also using CORS (Cross-Origin Resource Sharing).

How to Set Up the Project

You can work on this project using your favorite coding editor. In my case, I’ve used Visual Studio code, and there’s also Project IDX, which supports Firebase projects and makes it easy to develop there. Go for any editor you like best!

  1. You can start by cloning the GitHub repo.

  2. Install the required dependencies npm install.

How to Set Up Firebase

Below are the steps to set up the project; you can create a Firebase project either from the Firebase console or using the Command Line. The Firebase services we'll use are functions, hosting, and Firestore.

  • On the console, click to create a new project, give it a name, and click continue.

  • Select if you will use analytics.

  • Wait for the project to be created.

  • Set the Billing type under the gear -> Usage and Billing -> Details & Settings to Blaze (The Pay-as-you-go plan must use a third-party API).

  • Set the Google Cloud resource location in -> Project Setting.

How to Set Firebase Deploy Targets

Let’s set your deploy targets. Create a .firebaserc file in your project folder and update ‘PROJECT_ID’  with your project id. There’s a .firebaserc.example file showing where you can find it in the folder.

// .firebaserc

{

  "projects": {

    "default": "PROJECT_ID"

  }

}

Configure your Environment Variables

It’s time to add the environment variables to your project. 

From the /functions/.env.example file, you can create the /functions/.env file and include the following environment variables:

# .env

VONAGE_API_KEY=your_api_key

VONAGE_API_SECRET=your_api_secret

VONAGE_APPLICATION_ID=your_application_id

VONAGE_APPLICATION_PRIVATE_KEY=/path/to/your/private.key


# Use this URL to generate a new JWT: https://developer.vonage.com/en/jwt

JWT=your_jwt_token


# Number of hours to check SIM Swap events

MAX_AGE=72

Note: Secret Manager is a safe way to import environment variables. This tutorial uses dotenv, as Cloud Functions for Firebase supports dotenv.

How to Test Locally With Firebase Emulator

When testing locally, you can use the Firebase Local Emulator Suite.

  1. Initialize the emulators firebase init emulators.

  2. Start the emulators firebase emulators:start.

  3. You’ll find the URL for opening the local web application and Firestore instance in the command line. Open both pages and populate the Firestore instance. Remember that is your local Firestore instance. Therefore, it will differ from what you can find on the actual project in the cloud console.

Note: For this project, I’ve included them in the firebase.json file so you can find your emulator on port 5001 and Firestore on port 8080.

Deploy Your Web Application and Try it Out

How to Deploy with Firebase Hosting

Deploy your static files (HTML, CSS, JavaScript) to Firebase Hosting. Ensure you have the Firebase CLI installed and initialized in your project. Run the following command to deploy:

firebase deploy --only hosting

You can see that an HTML page will be generated for you in the Command Line. In my example, my project ID is ‘ account-recovery-demo’, and my generated URL is ‘https://account-recovery-demo.web.app’. Go ahead and open yours!

Cloud Functions for Firebase

Deploy your server-side logic using Firebase Functions. Ensure you have the Firebase CLI installed and initialized in your project. Run the following command to deploy:

firebase deploy --only functions

If you go to the ‘functions’  tab on your Firebase console project, you can spot the four functions: sendCode, login, verify and simSwap. If you need to check versioning and logs, you can check for each one of the created functions.

Firebase Cloud Firestore Database

Use Firestore to store user data and verification status. Create a 'credentials' collection and populate the Firestore fields with the credentials nodes.

Create each event node containing the following string-type fields: password, phone number, request_id, and username. We have stored these sensitive fields in the Firestore for this example app. Ideally, in a real application, these should be secured better using, for instance, Secret Manager.

A screenshot showing a collection created with one entry containing the fields password, phone_number, request_id, and usernameCloud Firestore Database Instance

Try It Out

It's time to go to the web application you've deployed using Firebase hosting.

The testing workflow should follow: imagine you've forgotten your password. Click on 'Forgot Password' to start the recovery. You'll be prompted to enter your phone number and request verification.

If the application detects a recent SIM swap, a warning pops up: Warning! A recent SIM pairing change related to the User’s mobile account occurred. Proceed?" If it wasn't you who did the swap, and you choose 'No, it wasn't me,' it's a sign there might be fraud happening with your number. This is your cue to check in with your mobile provider.

Note: In the tutorial demonstration, you're asked to confirm that you've swapped the SIM card; in a real-life scenario, the user would likely be invited to contact the service provider directly for additional identity checks. In a similar way, this approach could be applied to multifactor authentication on log-in, where a check would occur before sending the one-time token. If a recent SIM swap is detected, the user can contact the service provider directly for additional identity checks.

On the other hand, if you swapped your SIM and selected 'Yes, it was me', the app uses the Verify API to send a verification code to your phone. Enter this code on the next screen and set a new password. Once that's done, you can use your new credentials to log into your simulated bank account.

Conclusion

You've reached the end of this tutorial. Today, you saw how to improve your multi-factor application by adding Firebase Services to your web application. Connect with us on our Vonage Community Slack or message us on X.

Additional Resources

Amanda CavallaroDeveloper Advocate

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.

Subscribe to Our Developer Newsletter

Subscribe to our monthly newsletter to receive our latest updates on tutorials, releases, and events. No spam.