Frequently Asked Questions
Axios, a promise-based HTTP client, is used for making API calls from both the frontend (React) to the backend (Node.js) and the backend to the Infobip API.
Implement Infobip 2FA by setting up a Vite/React frontend, a Node.js/Express backend, and configuring Infobip's OTP service. The frontend sends API requests to the backend, which interacts with Infobip to send and verify OTPs via SMS. This guide provides step-by-step instructions and code examples for a complete setup.
Infobip provides a reliable and global communication platform with robust 2FA APIs, enabling secure user accounts and critical actions by verifying possession of a phone number through OTP, mitigating risks associated with compromised passwords.
The article recommends a monorepo with separate 'client' and 'server' directories. This helps organize the frontend (Vite/React) and backend (Node.js) code cleanly within a single project.
Configure environment variables before running the application. Store sensitive credentials like Infobip API keys, base URL, Application ID, and Message Template ID in a '.env' file on the backend (server-side). Load these via the 'dotenv' library.
Send a POST request to the correct Infobip API endpoint (e.g., your_instance.api.infobip.com/2fa/2/pin) with required data including 'applicationId,' 'messageId,' and the user's phone number in E.164 format, using appropriate authorization headers.
Send a POST request to the Infobip verification API endpoint (e.g., .../2fa/2/pin/PIN_ID/verify) containing the OTP entered by the user. In a production environment, retrieve the 'pinId' from server-side session storage.
The 'pinId' links the OTP request to the verification attempt. In production, store it securely on the server-side, associating it with the user's session. NEVER expose it client-side, unlike the demo code, as this introduces vulnerabilities.
The project uses a Vite (React) frontend for the user interface, a Node.js/Express backend to handle logic and API calls, and Infobip as the OTP provider. The user interacts with the frontend, which communicates with the backend, which in turn interacts with Infobip.
While Axios is recommended for its ease of use, other HTTP clients like 'node-fetch' or the built-in 'http' module can be used by adjusting the request-handling code on the backend (Node.js).
Configure the proxy in the 'vite.config.js' file to forward '/api' requests to your backend server address, like 'http://localhost:3001', to simplify development and avoid CORS issues.
Error codes include 401 (Unauthorized), 400 (Bad Request—often validation errors), 403 (Forbidden), and 500 (Internal Server Error). The article details these and potential causes, such as incorrect API key format, bad phone number format, or invalid application/message IDs.
CORS (Cross-Origin Resource Sharing) configuration is necessary to allow the frontend running on one port (e.g., 5173) to access the backend API running on a different port (e.g., 3001), which is common in development.
Key security practices include protecting your API keys, implementing rate limiting, using HTTPS, securing the 'pinId' server-side, and validating all user inputs.
OTP expiry is defined in the Infobip 2FA Application settings (PIN Time To Live or TTL). Set this to a short duration, like 5 minutes (5m), to enhance security.
Infobip 2FA Integration: Complete React + Node.js OTP Tutorial
Meta Description: Learn how to implement Two-Factor Authentication with Infobip OTP service. Step-by-step guide for building secure 2FA with React, Vite, and Node.js backend.
Enhance your application's security by adding a robust Two-Factor Authentication (2FA) layer using Infobip's OTP service. This guide walks you through integrating Infobip 2FA into a system with a Vite (React) frontend and a Node.js backend.
You'll build an application where users enter their phone number, receive an OTP via SMS powered by Infobip, and verify that OTP to gain access or confirm an action. This guide focuses on the core OTP request and verification flow for implementing secure two-factor authentication.
Project Overview and Goals
Problem Solved: Secure user accounts and critical actions by verifying phone number possession through OTP, mitigating risks from compromised passwords.
Technologies Used:
Architecture:
Outcome: A functional demonstration featuring a React frontend that allows users to request and verify OTPs sent via Infobip_ orchestrated by a Node.js backend API.
Prerequisites:
1. Setting Up Your 2FA Project Structure
Create a monorepo structure with separate directories for the client (Vite/React) and server (Node.js).
1. Create Project Directory:
2. Set Up Backend (Node.js/Express):
express
: Web framework for Node.js.dotenv
: Loads environment variables from a.env
file.cors
: Enables Cross-Origin Resource Sharing (necessary for frontend interaction).axios
: Makes HTTP requests to the Infobip API.Project Structure (Server):
3. Set Up Frontend (Vite/React):
Navigate back to the root directory (
infobip-2fa-app
):Project Structure (Client):
4. Configure Environment Variables (Backend):
Open the
server/.env
file and add placeholders for your Infobip credentials and configuration. You'll obtain these values from your Infobip account.dotenv
makes these accessible viaprocess.env
.2. Building the Node.js Backend API for OTP
Create two endpoints in your Express server: one to request an OTP and another to verify it.
Edit
server/server.js
:axios
for Infobip API calls due to its simplicity and promise-based nature.Authorization
,Content-Type
,Accept
) as required by Infobip./api/otp/request
endpoint in this demonstration returns thepinId
directly to the client. Never do this in production. Store thepinId
securely on the server (e.g., associated with the user's session) and never expose it client-side. This example prioritizes simplicity for demonstration over production security practices regardingpinId
handling. See the code comments for details.3. Integrating with Infobip 2FA Service
Configure Infobip and retrieve the necessary credentials for the 2FA process.
1. Sign Up/Log In to Infobip:
2. Obtain Base URL and API Key:
your_unique_id.api.infobip.com
) and generate an API Key..env
: Paste these values intoserver/.env
forINFOBIP_BASE_URL
andINFOBIP_API_KEY
. Treat the API Key like a password – keep it secret.3. Create a 2FA Application:
5m
for 5 minutes).sendPinPerPhoneNumberLimit: 5/1d
– 5 pins per number per day).applicationId
)..env
: Paste this ID intoserver/.env
forINFOBIP_APP_ID
.4. Create a 2FA Message Template:
NUMERIC
(most common).{{pin}}
placeholder where Infobip inserts the generated OTP. Example:Your verification code for My App is: {{pin}}. It expires in 5 minutes.
messageId
)..env
: Paste this ID intoserver/.env
forINFOBIP_MSG_ID
.Your
server/.env
file now has all the necessary values.4. Implementing the React Frontend with Vite
Create a React component to interact with your backend API.
1. Configure Vite Proxy (Optional but Recommended for Development):
Proxy API requests through Vite's dev server to avoid CORS issues during development without complex server configuration.
Edit
client/vite.config.js
:http://localhost:5173
).2. Create the Authentication Component:
Replace the contents of
client/src/App.jsx
with the following:3. Basic Styling (Optional):
Add some simple styles to
client/src/App.css
:useState
to manage component state (phone number, OTP, messages, loading status, UI visibility).handleRequestOtp
sends the phone number to the backend/api/otp/request
endpoint. Crucially, in this demo, it receives and stores thepinId
from the backend, which is insecure. On success, it shows the OTP input field.handleVerifyOtp
sends the (insecurely obtained)pinId
and the entered OTP to the backend/api/otp/verify
endpoint.axios
to make the API calls. The URLs (/api/...
) are relative because Vite's proxy handles forwarding them to the backend.showOtpInput
.inputMode=""numeric""
andautoComplete=""one-time-code""
to the OTP input for better UX.maxLength
to Infobip configuration.5. Error Handling and Logging for Production
server.js
):try...catch
blocks aroundaxios
calls to Infobip.console.error
). For production, use a structured logging library (like Winston or Pino) to log to files or external services, including request IDs for tracing.error.response.data
). Added specific checks for commonmessageId
values likePIN_NOT_FOUND
,WRONG_PIN
,MAX_ATTEMPTS_EXCEEDED
.{ success: false, message: '...' }
) with appropriate HTTP status codes (400, 500, etc.).App.jsx
):try...catch
blocks aroundaxios
calls to the backend API.error.response?.data?.message
).info
,error
,success
) for message styling.axios-retry
or manually within thecatch
block. However, retrying OTP verification itself is usually handled by letting the user re-enter the code or request a new one. Infobip handles rate limiting on their end based on your application settings.6. Security Best Practices for 2FA Implementation
INFOBIP_API_KEY
or other secrets to version control. Use.env
and ensure.env
is in your.gitignore
. In production, use secure environment variable management provided by your hosting platform.sendPinPerApplicationLimit
,sendPinPerPhoneNumberLimit
,verifyPinLimit
) to prevent abuse and control costs./api/otp/request
,/api/otp/verify
) using libraries likeexpress-rate-limit
to protect your own server resources from brute-force attempts.joi
orexpress-validator
offer more robust solutions.pinId
Handling (CRITICAL REMINDER): As stressed multiple times, do not exposepinId
to the client in production. This example does so for simplicity only. The correct approach involves storing thepinId
securely on the server-side, linked to the user's session, and retrieving it during verification based on that session.pinAttempts
setting helps mitigate OTP brute-forcing. Your backend rate limiting adds another layer.7. Troubleshooting Common Infobip 2FA Issues
401 Unauthorized
: IncorrectINFOBIP_API_KEY
or Base URL. Check.env
and Infobip portal. Ensure theAuthorization
header format isApp YOUR_API_KEY
.400 Bad Request
(on Request OTP): Often invalid phone number format (needs E.164), incorrectapplicationId
ormessageId
, or missing required fields. Check Infobip API docs and your request payload. Also check Infobip rate limits.400 Bad Request
(on Verify OTP):PIN_NOT_FOUND
(invalidpinId
provided by client (due to demo flaw) or expired session),WRONG_PIN
(incorrect OTP entered),MAX_ATTEMPTS_EXCEEDED
(configured limit reached). CheckpinId
handling (server-side in production!), user input, and Infobip settings.403 Forbidden
: Sometimes related to sender ID issues, geographic restrictions, or account permissions. Check Infobip configuration and account status.500 Internal Server Error
: Issue on Infobip's side. Retry might be appropriate depending on the context.INFOBIP_APP_ID
andINFOBIP_MSG_ID
in.env
exactly match the IDs created in the Infobip portal. Ensure thePIN Length
configured in the Infobip Message Template matches themaxLength
attribute on the OTP input field in the frontend (App.jsx
).cors
middleware on the backend (server.js
) correctly allows the origin of your frontend (e.g.,http://localhost:5173
). Check the browser's developer console for specific CORS error messages.447123456789
for a UK number,14155552671
for a US number). Ensure users input numbers correctly or implement frontend/backend formatting/validation.pinId
in this example (passing it to the client) is insecure and for demonstration purposes only. Implement server-side storage forpinId
in any real application.Frequently Asked Questions (FAQ)
Q: What is Infobip 2FA and how does it work?
A: Infobip 2FA (Two-Factor Authentication) is a security service that verifies user identity by sending One-Time Passwords (OTPs) via SMS. Users receive a temporary code on their phone, which they enter to confirm their identity. This adds an extra security layer beyond passwords.
Q: How do I get Infobip API credentials for 2FA?
A: Log in to your Infobip account, navigate to API Keys section to generate an API Key and find your Base URL. Then create a 2FA Application and Message Template in the Infobip portal to obtain your Application ID and Message Template ID.
Q: What phone number format does Infobip require?
A: Infobip requires E.164 format – digits only without
+
, spaces, or hyphens. Examples:447123456789
(UK),14155552671
(US). Implement validation on both frontend and backend to ensure correct formatting.Q: Why is my OTP code not being delivered?
A: Check these common issues: incorrect phone number format (must be E.164), wrong Infobip credentials in
.env
, exceeded rate limits in your Infobip Application settings, or sender ID restrictions in the destination country. Verify your Infobip account has sufficient credits.Q: How long should OTP codes remain valid?
A: Set the PIN Time To Live (TTL) to 5-10 minutes in your Infobip Application settings. Shorter durations (5 minutes) provide better security, while longer durations (10 minutes) improve user experience. Balance security with usability for your use case.
Q: Should I store the pinId on the client side?
A: Never store
pinId
on the client in production. This demo does so for simplicity only. Always storepinId
securely on the server, linked to the user's session, and retrieve it during verification. ExposingpinId
to clients creates significant security vulnerabilities.Q: How do I prevent OTP brute-force attacks?
A: Implement multiple layers: configure
pinAttempts
(e.g., 5 max attempts) in your Infobip Application, add rate limiting on your backend endpoints usingexpress-rate-limit
, set rate limits per phone number in Infobip settings, and implement exponential backoff for failed attempts.Q: Can I use Infobip 2FA with Vue.js instead of React?
A: Yes. The backend Node.js/Express code remains identical. Replace the React frontend (Section 4) with Vue.js components using the same API calls via Axios. The OTP request and verification logic stays the same regardless of frontend framework.
Q: What HTTP status codes does Infobip return?
A: Common codes:
200
(success),400
(bad request – invalid phone format, wrong OTP, max attempts exceeded),401
(unauthorized – invalid API key),403
(forbidden – sender ID or geographic restrictions),500
(Infobip server error).Q: How do I test Infobip 2FA without incurring SMS costs?
A: Infobip offers free trial accounts with limited credits. Test with a verified phone number (usually the one used during registration). For extensive testing, consider using Infobip's test mode or sandbox environment if available for your account tier.
Q: What are the best practices for production 2FA deployment?
A: Use HTTPS for all communications, store API keys in secure environment variables (never in code), implement server-side
pinId
storage with session management, add rate limiting on all endpoints, validate all inputs thoroughly, use structured logging for debugging, and integrate 2FA into your existing authentication system with proper session handling.