Enable 2-Step Verification in Strapi using Twilio
Strapi is a headless CMS built using Nodejs, it allows developers to create custom content types easily, add validation rules and handle User Authentication out of the box, so Mobile developers can simply build an API for their Apps with a CMS to filter data easily. However, the Buzz killer here is that Strapi doesn’t support 2-Step Verification, although this feature was added to the roadmap since 2018.
Fortunately, Strapi was built as a collection of packages so it’s customizable using what is known as extensions. This means that we can choose any package and customize it. In our situation, we want to customize User Auth, so our targeted package isusers-permissions
.
Strapi’s Auth
Currently, Strapi handles User Auth using two controllers, User.js
& Auth.js
which can be located inside node_modules/strapi-plugin-users-permissions/controllers/
.
Username and Email should be unique, and if we open User.js
and navigate to create
method, we can see that it’s checking whether the same username or Email are already taken to halt the registration process.
const userWithSameUsername = await strapi
.query('user', 'users-permissions')
.findOne({ username });// Andconst userWithSameEmail = await strapi.query('user', 'users-permissions').findOne({ email });
Override
What we want to achieve here is to have a verification code sent to the user when registering as this is so handy for Mobile Developers. So first, we need to add two new fields to the User entity using Strapi’s dashboard. Let’s create token
& phone
fields with type String
. Now, let’s dive into the coding part.
Let’s create an extension for the users-permissions
package. In the root folder create extensions/users-permissions/controllers
. Then we need to create a new file named User.js
to override the original one.
Before diving too much I’ve to clarify one thing, by default Strapi registers some routes such as create, update, me, …etc, So if you don’t want to change their behavior just don’t include them in your new User.js. But since we are overriding the create method, we have to include it in our new User.js
extension.
As you can see from the code snippet above, we overrode the create method accepting only phone & username from the user, and then we check if the same number is already used, if not, we just create the token and then send it to the user’s phone after creating the user Object & storing it inside our DB.
Try to make a POST call to localhost:1337/users
with phone and username in the body and things should be working as expected. And just one note, we can use the same logic inside Auth.js
when overriding register
method, But since we are in control of the flow, we can make our App call any endpoint we want as long as it’s doing the job.
Let’s create a new method to verify the user’s account and send a token to be used in future API calls.
Now let’s register the new method and enable it. First, inside extensions/users-permissions
we need to create config
folder with routes.json
file
Last, but not least, from Starpi’s dashboard we navigate to Roles & Permissions -> Public ->Users-Permissions and then we click on VerifyAccount
under the User
entity, then we hit Save. Now we can make a POST call to localhost:1337/users-permissions/verify
with phone & token to check if the user got it right, and if that is the case, we will have a token to be used in our calls to any protected route.
If you got an error about email field being required, please modify User.settings.json
which is located inside extensions/users-permissions
so the email key will be like this
"email": {
"type": "email",
"minLength": 6,
"configurable": false
}