Implement SMS OTP/2FA in Next.js with NextAuth and Plivo - code-examples -

Frequently Asked Questions

Implement 2FA by integrating NextAuth.js for authentication, Plivo for SMS delivery, and Prisma for database management. This setup enables a secure login flow where users verify their identity with an OTP sent via SMS after entering their credentials, enhancing account security.
Plivo is the communications platform API used to send SMS messages containing the One-Time Passwords (OTPs) for two-factor authentication. It's a key component for delivering the verification codes to users' phones.
NextAuth.js uses JSON Web Tokens (JWT) to manage session state and store authentication information, including whether 2FA has been verified in the current session. This approach enhances security by encoding user data and verification status within the token itself.
Use SMS-based OTP authentication to enhance security when users log in with credentials. After initial login, if 2FA is enabled, an OTP is required before granting full access to protected resources like a dashboard.
Yes, Prisma supports multiple database providers including PostgreSQL, MySQL, and SQLite. While the example uses PostgreSQL, you can adapt the schema and database URL in `schema.prisma` and `.env` to your preferred database.
Configure the Plivo Node.js client by setting environment variables (`PLIVO_AUTH_ID`, `PLIVO_AUTH_TOKEN`, `PLIVO_PHONE_NUMBER`) with your Plivo credentials. The `sendSms` utility function in `plivo.ts` then handles sending SMS messages using these credentials.
Hashing the OTP with bcrypt before storing it in the database significantly enhances security by preventing the storage of sensitive information in plain text. Only the hash is stored, and the submitted OTP is compared against the hash for verification.
The `verifyOtp` utility function handles OTP expiry by comparing the current time to the stored `twoFactorExpiry` timestamp. If expired, it clears the OTP data and returns false, prompting the user to request a new code.
The provided code uses `next-auth@beta`, specifically for compatibility with the Next.js App Router and Server Actions. The beta version supports the latest features and conventions of the App Router.
The `middleware.ts` file configures route protection by checking the `twoFactorVerified` status within the session. If 2FA is enabled but not verified, the middleware redirects to the /verify-otp page.
The `twoFactorVerified` flag in both the session and JWT indicates whether a user has successfully completed 2FA for the current session. This ensures protected routes are only accessible after both credential and OTP verification.
The `generateOtp` utility function uses the `otp-generator` library to create secure, numeric OTPs of a specified length (default is 6 digits). This function ensures the randomness and format of the codes.
Two configurations (`auth.config.ts`, `auth.ts`) are used to accommodate Next.js middleware. `auth.config.ts` contains minimal callbacks and settings needed for early checks before full initialization in `auth.ts`.
If Plivo credentials are missing during development, the `sendSms` function logs a warning and simulates sending the SMS instead of throwing an error. This allows development to proceed without actual SMS delivery.