> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Two-Factor Authentication

> Set up SMS-based two-factor authentication with OTP using Plivo APIs

Two-factor authentication (2FA) can play a key role in securing your applications against password data breaches. Authentication with a one-time password (OTP) delivered to your users over SMS is an effective approach to implementing two-factor authentication. Plivo’s premium direct routes guarantee the highest possible delivery rates and the shortest possible delivery times for your 2FA SMS messages.

This guide shows how to set up SMS-based two-factor authentication using either {/* [PHLO](/docs/phlo/getting-started/getting-started) */} or traditional API development. PHLO lets you create and deploy workflows from an intuitive graphical canvas in few clicks.

<Tabs>
  <Tab title="Using API">
    Here’s how to implement 2FA using Plivo APIs.

    <h2 id="xml-prerequisites">Prerequisites</h2>

    To get started, you need a Plivo account —  [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment.

    <h2 id="xml-set-up-the-demo-application-locally">Set up the demo application locally</h2>

    * Clone the 2FA demo repository from [GitHub](https://github.com/plivo/2fa-dotnet-demo).

    ```sh theme={null}
    $ git clone https://github.com/plivo/2fa-dotnet-demo.git
    ```

    * Change your working directory to 2fa-dotnet-demo.

    ```sh theme={null}
    $ cd 2fa-dotnet-demo
    ```

    * Open the 2fa folder in Visual Studio.

    * Edit appsettings.json. Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Replace the PHLO ID with `null`.

    <Frame>
      <img src="https://mintcdn.com/plivo/2OFvQXVNT3srKLUy/images/dotnet-config.png?fit=max&auto=format&n=2OFvQXVNT3srKLUy&q=85&s=a1e9829cb2e1a80c4d4a0f50ba43d99e" alt="Configuration file" width="1441" height="900" data-path="images/dotnet-config.png" />
    </Frame>

    <h2 id="xml-a-review-of-the-code">A review of the code</h2>

    Let‘s walk through what the code does.

    <h3 id="xml-generate-the-otp">Step 1:  Generate the OTP</h3>

    Use the Time-Based OTP algorithm to generate a random six-digit one-time password (OTP).

    ```cs theme={null}
    Random r = new Random();
    var code = r.Next(999999);
    ```

    <h3 id="xml-send-sms-message-with-otp">Step 2: Send an SMS message with the OTP</h3>

    Send an SMS message with the OTP to the user’s registered mobile number using Plivo’s Send Message API.

    ```cs theme={null}
    public int SendVerificationCodeSms(String DstNumber, String Message)
    		{
    			Random r = new Random();
    			var code = r.Next(999999);
                var response = Client.Message.Create(
                    src: AppNumber,
                    dst: DstNumber,
                    text: Message.Replace("__code__", code.ToString()));
                return code;
    		}
    ```

    <h3 id="xml-make-a-phone-call-with-otp">Failover: Make a phone call with the OTP</h3>

    If the SMS message doesn’t reach the mobile device, the user can request a voice OTP.

    ```cs theme={null}
    public int SendVerificationCodeCall(String DstNumber)
    		{
    			Random r = new Random();
    			var code = r.Next(999999);
                var response = Client.Call.Create(
                    to:new List<String>{DstNumber},
                        from:AppNumber,
                        answerMethod:"POST",
                        answerUrl:"https://twofa-answerurl.herokuapp.com/answer_url/"+code);
                return code;
    		}
    ```

    <h3 id="xml-verify-the-otp">Step 3: Verify the OTP</h3>

    Verify the OTP the user entered on their handset.

    ```cs theme={null}
    public string Index(string number, string code)
    		{
    			ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(_configuration.GetValue<string>("RedisHost"));
    			IDatabase conn = redis.GetDatabase();

    			string key = $"number:{number}:code";
    			var compare_code = (string)conn.StringGet(key);
    	
    				if (compare_code == code)
    				{
    					conn.KeyDelete(key);
    					Verification verification = new Verification();
    					verification.status = "success";
    	                verification.message = "Number verified";
    					string output = JsonConvert.SerializeObject(verification);
    					return output;
    				}
    				else if(compare_code != code)
    				{
    					Verification verification = new Verification();
    					verification.status = "failure";
    					verification.message = "Number not verified";
    					string output = JsonConvert.SerializeObject(verification);
    					return output;
    				}
    			
    				else
    				{
    					Verification verification = new Verification();
    					verification.status = "failure";
    					verification.message = "number not found";
    					string output = JsonConvert.SerializeObject(verification);
    					return output;
    				}
    		}
    ```

    <h2 id="xml-test">Test</h2>

    To test the application, start the Redis server.

    ```sh theme={null}
    $ redis-server
    ```

    Build and run the application from Visual Studio.

    <Frame>
      <img src="https://mintcdn.com/plivo/2OFvQXVNT3srKLUy/images/dotnet-run.png?fit=max&auto=format&n=2OFvQXVNT3srKLUy&q=85&s=bebc128cf1d97f801d3fbf78d8054936" alt="Dotnet Run" width="1440" height="900" data-path="images/dotnet-run.png" />
    </Frame>

    Set up ngrok to expose your local server to the internet.

    You should be able to see the application in action at https\://\<ngrok\_identifier>.ngrok.io/.

    The finished application should look like this.

    <Frame>
      <video autoplay loop muted inline width="560" height="315">
        <source width="560" height="315" src="https://mintcdn.com/plivo/9TcugqK5W7G3A-xp/images/two-factor.mp4?fit=max&auto=format&n=9TcugqK5W7G3A-xp&q=85&s=520e7f7b48a0063c0cbee11c213631cb" type="video/mp4" data-path="images/two-factor.mp4" />
      </video>
    </Frame>
  </Tab>
</Tabs>
