Search code examples
c#asp.net-mvcauthenticationauthorizationone-time-password

How to register mobile numbers with One-Time-Password (OTP) in ASP.NET core MVC, not using 2FA


I'm creating an application in ASP.Net core MVC that requires user registration and verifying with an OTP by only entering their mobile phones.

I'm currently using Twilio to send SMS (do not want to use Twilio Verify only Twilio SMS) and I'm creating my own OTP by randomly generating 4 digits.

So to my question: How do I use this 4 digit OTP that I get on my phone and register the mobile phone and make sure the user is logged in?

I do not want to implement 2FA at the moment because it requires username and password.

This question is similar to: 'https://stackoverflow.com/questions/43862276/register-with-phone-number-instead-of-email-using-mvc-identity' But it has gone 4 years with no answer...

I appreciate any help, tips or/and further resources, thanks in advance!


Solution

  • OTP and User Login/Registration are two separate process. It is the developers who decide how OTP and Login/Registration will be connected. I have implemented this requirement couple of months ago. Here is how you can do this:

    • 1st step: User inputs a valid phone number. Then redirect the user to a screen where he can input an OTP (Optional - the phone number from the previous step can be in a hidden field)
    • 2nd step: Generate the 4 digit OTP and store the phone number and the OTP in a database lets call it 'OTP' table. Send the OTP to the user
    • 3rd Step: On the OTP input screen user inputs the OTP
    • 4th Step: Check the OTP in the 'OTP' table. If the OTP is Valid then:
      • If the phone number exists in the 'User' table then this is a returning user. Login this user in step 5. You already have this User ID in the 'User' table
      • If the phone number does not exists in the 'User' table then create the user profile with the phone number only (You can get the other information like Name later). After that login the user in step 5
    • 5th Step: Login the user. To do this you just need an user entity which you already have from the previous step. To login you can implement any login provider. I would suggest use JWT (JSON Web Token) to authentication.

    When you have the user who has successfully verified an OTP, use the User ID to authenticate the user. Here is how you can implement JWT:

    private string GenerateJSONWebToken(UserModel userInfo)    
    {    
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));    
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);    
    
        var token = new JwtSecurityToken(_config["Jwt:Issuer"],    
          _config["Jwt:Issuer"],    
          null,    
          expires: DateTime.Now.AddMinutes(120),    
          signingCredentials: credentials);    
    
        return new JwtSecurityTokenHandler().WriteToken(token);    
    }
    

    That will generate a token with 120 minute validity like this:

    {    
    "token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJKaWduZXNoIFRyaXZlZGkiLCJlbWFpbCI6InRlc3QuYnRlc3RAZ21haWwuY29tIiwiRGF0ZU9mSm9pbmciOiIwMDAxLTAxLTAxIiwianRpIjoiYzJkNTZjNzQtZTc3Yy00ZmUxLTgyYzAtMzlhYjhmNzFmYzUzIiwiZXhwIjoxNTMyMzU2NjY5LCJpc3MiOiJUZXN0LmNvbSIsImF1ZCI6IlRlc3QuY29tIn0.8hwQ3H9V8mdNYrFZSjbCpWSyR1CNyDYHcGf6GqqCGnY"    
    }
    

    Send the JSON token to the application/mobile app. As long as the application/mobile app has the token and sends it along the requests (in header) the app and user is authenticated. You have to check the token and its validity against a Database table. Here is a complete implementation of the JWT part.