Authenticate Laravel Users Using JWTs and Twilio's WhatsApp Business API
Time to read: 6 minutes
Web applications need a way of identifying users in order to serve dynamic data back to users. The process of collecting and storing data when a user registers, validating the data and recognizing a unique user when the user logs in is the authentication flow.
As mankind continues to evolve, cybercrimes continue to increase by the day. The security of user’s data and their privacy becomes more important than ever. In the quest to achieve this, security measures such as the popular 2-step verification (2FA verification) are put in place.
Implementing 2FA (Two-Factor Authentication) verification in modern web applications can be tricky. Nonetheless, do not worry as the Twilio API for WhatsApp has plenty of documentation and support to make this possible for developers.
This tutorial is intended to teach you about the Twilio API for WhatsApp and custom token-based authentication in Laravel using JSON Web Tokens (JWTs). By the end of the tutorial you will have developed:
- A simple Laravel application/API with a complete user authentication flow
- A 2FA authentication layer that sends verification codes to users using WhatsApp
- Tests for the code/API endpoints using Postman
Prerequisites
To follow along with this tutorial you should have the following:
Create a new Laravel project
Let's get started building our Laravel application by using this Composer command:
If you have the Laravel installer installed, you can use the following command:
Regardless of the command you used, a new Laravel project will have been created in twilioLaravel
. Switch to that folder by running cd twilioLaravel
. Then, install the tymon-jwt
package for Laravel by using the following Composer command:
NOTE: At the time of publication, there is a problem with the production version of the package. Therefore, we installed the development version.
Now we have to make a few important changes to get jwt-auth
to work properly with our application. Add the following declaration to the Package Service Providers…
section of the providers
array, in your config/app.php
file:
Now add the following Facades to the aliases
array in config/app.php
:
With those changes made, let’s publish the config file for JWT with the following Artisan command:
Now set the jwt-auth
secret using the following Artisan command:
At this point, we can serve our project and view it in our browser. This will allow us to verify that the project setup worked correctly. Serve it using the following command:
Our server should start up on port 8000 and return the following message:
If we open http://127.0.0.1:8000 in a browser, we should see the default Laravel home page, as in the example below.
Set up the database and run migrations
It's time to set up our database and run migrations in our Laravel application. But before you can do that, you have to set your database credentials in .env
. We are using a MySQL database. Feel free to give your database a different name from mine, if you’d like.
We will need an additional column added to the user
table to contain the one-time password. In our migrations folder, add the following declaration in database/migrations/2014_10_12_000000_create_users_table.php
file.
You can now run your migration using the following Artisan command:
Create the controllers and models
Now we have our application up and running. We need to make a few changes to both the User
model and the authentication
controllers to get tymon-jwt
up and running. Let's get started with the User
model. Modify app/Models/User.php
as shown in the following code sample:
The getJWTidentifier()
and getJWTCustomClaims()
methods were added to the User
model (user.php
) to enable jwt to work properly. With those changes made, let us proceed by creating an authentication controller in Laravel using the following command:
Next, edit the newly created UserController
as shown in the following code sample below. Feel free to copy and paste this to your controller, located at app/Http/Controllers/UserController.php
.
UserController
now contains three methods: authenticate
, register
, and getAuthenticatedUser
. The authenticate
method logs the user in and generates a JWT token for the session. The register
method, as the name implies, validates and creates a new user account. The getAuthenticatedUser
method fetches the data of the logged-in user.
Set up routes for the process
We next need routes to test our application endpoints. To create our routes, open routes/api.php
and modify the content as seen here:
The routes we defined will give our application the ability to register users at http://127.0.0.1:8001/api/register and authenticate users to login at http://127.0.0.1:8001/api/login.
User registration using Postman
At this point, we should be able to test our application using an API testing tool such as Postman. Let’s use the app to register a new user. Open Postman and create a new POST
request to http://127.0.0.1:8001/api/register. Select the Body tab, then the form-data option, and then provide the following parameters:
- name
- password (it must be at least 6 characters long)
- password_confirmation
After adding the four parameters, click Send to submit the request. User registration should return a JSON response containing the user’s details and an auth token, like the image below:
User login using Postman
Let's continue our testing by logging in the newly created user using Postman. Create a new POST
request to http://127.0.0.1:8001/api/login and supply the following parameters:
- password
A successful login will return the user’s token as shown in the previous image.
Twilio API for WhatsApp
I’m glad you made it this far as the project is halfway done. We have successfully implemented the Tymon JWT authentication library and created two endpoints for user login and registration. Now it's time to implement 2FA verification into our application using the Twilio API for WhatsApp.
WhatsApp Sandbox setup
You need a verified phone number to interact with the WhatsApp API. This verification process can take days, but in the meantime the WhatsApp sandbox provides an avenue for developers to test their code while awaiting number verification.
To set up the Twilio WhatsApp Sandbox:
- Log in to your Twilio console (Create an account if you do not have one)
- Open Twilio Sandbox for WhatsApp
- Send the displayed code to the WhatsApp Sandbox number provided
In most cases, this number is often the same. The code has a unique format of "join-{unique word}"
.
If the code was successfully received by the Sandbox, you should see a reply like the following:
We next need to update our .env
file to add all relevant Twilio credentials. Add the following values to your .env
:
The TWILIO_WHATSAPP_NUMBER
is the Sandbox number. Other details above can be found in your Twilio Console settings, as the following image shows.
Send a 2FA verification code to WhatsApp
We now need to install the Twilio PHP SDK for Laravel. Composer will allow us to install it within our project. To do so, run the following command in the project directory:
In order to keep things a little more organized, let’s create a Trait in our Laravel application that sends out WhatsApp messages. In the app
directory of your application, create a folder called Traits
. Then, create a new file in the directory and name it WhatsAppMessageTrait.php
. You can call your file something else if you would like.
Let us update our newly created Trait file to send WhatsApp messages.
The sendOtp()
method fires off the message using data from the .env file and those provided within the $message
variable which holds the message. Now we can use our WhatsAppMessageTrait
in our UserController
for our 2FA verification. To do that, modify the authenticate
method in the UserController
so that we can receive a one-time verification code in our sandbox to enable us to log in, by adding the following declaration to the header:
Then, replace the contents of the authenticate
method with the following code in the UserController
class:
In my case here, notice that the recipient phone number is coming from the .env
file. Modify your .env file and add the phone number as an environment variable like mine below.
In a real world application, the phone number would most likely be received through an input form. Feel free to tweak this to suit your exact needs. The sendOtp
method is coming from our trait. The saveOtpCode
method is a protected method that saves the generated OTP code in the user table. The generateCode
method can be found in our trait. We can add the saveOtpCode
method by modifying our UserController
and adding the following:
The Verify method
We need another method and route to verify the code sent and received. Create verifyOtp
method in UserController
using the following code:
Also, add the following to the API route to routes/api.php
:
Testing
Let us proceed to test our application using Postman once more. Re-submit the login request that you previously submitted.
Confirm that the OTP is received in WhatsApp.
To verify the OTP code and complete the authentication flow, we need to call the verifyOtp
route. We can test this in Postman too by submitting the OTP verification code and the user’s email address in a form. In my case my OTP verification code is 956477095. The image below shows the verification process using Postman.
Conclusion
I am glad you made it this far. By now, you should:
- Have a firm understanding of how
tymon/jwt-auth
works in Laravel - Have set up the WhatsApp Sandbox for Twilio
- Be able to consume the Twilio WhatsApp API for 2FA authentication
- Have created a token-based authentication system using Laravel, JWT, and the Twilio API for WhatsApp
- Have tested the app with Postman
Here’s a link to the complete project on GitHub.
Bio:
My name is Anumadu Udodiri Moses. I am a software developer and a technical content creator in the PHP and JavaScrip ecosystem. I run a gaming community called Tekiii. You can reach out to me on LinkedIn.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.