Enterprises are increasingly challenged to keep sensitive information from falling into the wrong hands. This means that we can no longer trust old online authentication systems that rely solely on usernames and passwords, especially as security breaches grow in frequency, severity and sophistication.
With the MessageBird Verify API, you can implement two factor authentication (2FA) solutions to provide an additional layer of account security by verifying the user's password with a second authentication token and in turn, secure customer data, block fraudulent accounts, and safeguard key transactions in a matter of minutes. The most common use case involves the application of one-time passwords (OTP) generated by hardware tokens or authenticator apps or directly sent to the user's mobile phone via SMS text messaging.
In this MessageBird Developer's Guide, we'll introduce the MessageBird Verify API and show you how to build a runnable application in Node.js. The application is a prototype for a two factor authentication system deployed by our fictitious online banking application called BirdBank.
We'll walk you through the following steps:
- Asking for the phone number
- Sending a verification code
- Verifying the code
Pro-tip: Follow this tutorial to build the whole application from scratch or, if you want to see it in action right away, you can download, clone or fork the sample application from the MessageBird Developer Guides GitHub repository.
We'll build the sample web application using Microsoft Visual Studio. To follow this Developer Guide and run the sample application, we'll need to have Visual Studio (2012 or later) installed. Learn more about the latest available Visual Studio editions here. Note that you'll need to install the Visual Studio edition that matches your usage scenario (explained in Supported Usage Scenarios).
Now, its time to download, clone or fork the sample web application from the MessageBird Developer Guides GitHub repository. Once you've done this, let's open the solution file verify-guide-csharp.sln
in Visual Studio.
The solution file contains the verify-guide-csharp-project, which is where we've stored our application source files. The application is written using ASP.NET Web Forms, which is a simple ASP.NET framework. We use Web Forms to add some structure to the code and keep the web page presentation separate from processing logic. Later, we will explore the application source files.
But first, let's install the libraries (packages) that are needed to get our application working. On the main menu in Visual Studio, click Tools | NuGet Package Manager | Package Manager Console. The Package Manager Console will open and you will see a command prompt. Type each line below one-by-one and press ENTER after each line:
Install-Package Microsoft.Net.Compilers -ProjectName verify-guide-csharp-project -Version 2.8.2 Install-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform -ProjectName verify-guide-csharp-project -Version 2.0.0 Install-Package MessageBird -ProjectName verify-guide-csharp-project -Version 1.3.5.1 Install-Package Newtonsoft.Json -ProjectName verify-guide-csharp-project -Version 11.0.2 Install-Package DotNetEnv -ProjectName verify-guide-csharp-project -Version 1.2.0
The five packages are now installed! The Microsoft packages are low-level packages that are needed to use ASP.NET. The MessageBird package contains the Verify APIs. The DotNetEnv package will allow us to retrieve your API key as an environment variable.
We won't need to use the Package Manager Console window, so let's go ahead and close it.
Now, let's open the Solution Explorer. We will use it to view our project files. You should see the Solution Explorer open on the right - if not, go to View | Solution Explorer on the main menu in Visual Studio.
Our sample application contains three web pages. To avoid coding the same header and footer HTML tags into each page, we've created a MasterPage.master
file that specifies these tags. In this file, you will see these tags above and below the ContentPlaceHolder
. The ContentPlaceHolder
contains the unique content that is rendered on each page.
The first step in verifying a user's phone number is asking them to provide their phone number. In Step1.aspx
you'll find a basic HTML form with a phone number input text box and a button:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Step1.aspx.cs" Inherits="Step1" %>
<asp:Label id="ErrorLabel" runat="server"></asp:Label>
<p>Please enter your phone number (in international format, starting with +) to receive a verification code:</p>
<form id="Step1Form" runat="server">
<asp:TextBox id="PhoneNumberTextBox" runat="server"></asp:TextBox>
<asp:Button ID="SendCodeButton" runat="server" Text="Send code"
OnClick="SendCodeButton_Click"/>
</form>
When our user clicks on the button, the SendCodeButton_Click
method runs on the code behind page. This method is shown below in Step1.aspx.cs
:
// Using statements not included (for brevity)
public partial class Step1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Show an error if this page was previously called and CreateVerify generated an error
if (Session["Error"] != null)
ErrorLabel.Text = Session["Error"].ToString();
}
protected void SendCodeButton_Click(object sender, EventArgs e)
{
// Check if phone number is empty
if (PhoneNumberTextBox.Text.Length == 0)
{
Session["Error"] = "Phone number cannot be empty.";
Server.Transfer("Step1.aspx");
return;
}
// Load the API key using the DotNetEnv library
DotNetEnv.Env.Load(System.AppDomain.CurrentDomain.BaseDirectory + "/APIKey.env");
String YourAccessKey = System.Environment.GetEnvironmentVariable("MESSAGEBIRD_API_KEY");
// Initalize the MessageBird API
MessageBird.Client client = MessageBird.Client.CreateDefault(YourAccessKey);
Session["client"] = client;
// Call CreateVerify to send a verification code to the user's phone. Here, we are sending "null" as the second
// input. This input specifies optional settings, such as the timeout. Since we are sending "null", the default
// timeout is used, which is 30 seconds.
try
{
Verify verify = client.CreateVerify(PhoneNumberTextBox.Text, null);
Session["VerifyId"] = verify.Id;
}
catch (ErrorException errorException)
{
Session["Error"] = ErrorGenerator.Generate(errorException);
Server.Transfer("Step1.aspx");
}
Server.Transfer("Step2.aspx");
}
}
Right away, we check if the length of the phone number the user entered is 0. If it is, the phone number is empty and the user will be prompted to re-enter it. In this case, the page calls itself via Server.Transfer
.
If the phone number is populated correctly, the application will retrieve your API key as an environment variable. This is done via the DotNetEnv library. Rather than hardcoding the API key directly in Step1.aspx.cs
, we've created a separate APIKey.env
file to store the key. You shouldn't hardcode API keys in any files that you will be storing in a version control system, such as Git and Team Foundation Version Control (TFVC). So, if you were to store this sample application in a version control system, you wouldn't add APIKey.env
.
Now, to create the file, go to the Solution Explorer, right click "verify-csharp-project", click Add | Add New Item... In the name field, specify APIKey.env
and click Add. With file now open, enter the line:
MESSAGEBIRD_API_KEY=YOUR-API-KEY
Replace YOUR-API-KEY
with your API key. Keys can be created or retrieved from the API access (REST) tab in the Developers section of your MessageBird dashboard.
Switching back to Step1.aspx.cs
, we initialize the MessageBird client API via the CreateDefault
method and pass in your API key.
Next, we store a reference to the MessageBird client in an ASP.NET session variable. We'll use this this variable later.
Continuing with our walk-through of Step1.aspx.cs
, we call the Verify
method, which sends a verification code to the phone number that the user entered in the form. The MessageBird Verify API takes care of generating a random code, so you don't have to do this yourself. Codes are numeric and six digits by default. If you want to customize the length of the code or configure other options, you can check out the Verify API documentation.
If all is well, the page Step2.aspx
is rendered. The details of this are explained in the Verifying the Code section below.
But, if there's an error while Verify
executes, an ErrorException
is thrown. We handle the exception by invoking the Generate
method of the ErrorGenerator
class. This class is stored in the ErrorGenerator.cs
file in the App_Code
folder. This Generate
method builds the error string, which is then stored in a Session
variable. Then the page calls itself via Server.Transfer
. The Page_Load
method detects that there is an error, so it populates the ErrorLabel
on the form in Step1.aspx
, which displays the error to the user. Then the user is prompted to enter their phone number again.
Once the code is delivered, our user will check their phone and enter the code into the textbox in the form in Step2.aspx
below.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Step2.aspx.cs" Inherits="Step2" %>
<asp:Label id="ErrorLabel" runat="server"></asp:Label>
<p>We have sent you a verification code!</p>
<p>Please enter the code here:</p>
<form id="Step2Form" runat="server">
<asp:TextBox id="CodeTextBox" runat="server"></asp:TextBox>
<asp:Button ID="CheckCodeButton" runat="server" Text="Check code"
OnClick="CheckCodeButton_Click"/>
</form>
When the user clicks on the button, the CheckCodeButton_Click
method runs on the code behind page Step2.aspx.cs
: (Note the terms "code" and "token" used here mean the same thing).
// Using statements not included (for brevity)
public partial class Step2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Show an error if this page was previously called and SendVerifyToken generated an error
if (Session["Error"] != null)
ErrorLabel.Text = Session["Error"].ToString();
}
protected void CheckCodeButton_Click(object sender, EventArgs e)
{
// Check if code is empty
if (CodeTextBox.Text.Length == 0)
{
Session["Error"] = "Verification code cannot be empty.";
Server.Transfer("Step2.aspx");
return;
}
// Call SendVerifyToken to verify the code entered in CodeTextBox.Text matches the code
// sent to the user in the CreateVerify call in Step1.aspx.cs. Here, the words "token" and "code"
// mean the same thing.
try
{
Client client = ((Client)Session["Client"]);
client.SendVerifyToken(Session["VerifyId"].ToString(), CodeTextBox.Text);
}
catch (ErrorException errorException)
{
Session["Error"] = ErrorGenerator.Generate(errorException);
Server.Transfer("Step2.aspx");
}
Server.Transfer("Step3.aspx");
}
}
Right away, we check if the length of the code the user entered is 0. If it is, the code is empty and the user needs to reprompted to enter it. In this case, the page calls itself via Server.Transfer
.
If the code is populated, we call the SendVerifyToken
method with two inputs: the code just entered by the user, and the VerifyId that was generated in Step1.aspx.cs
as a result of calling the Verify
method. (This VerifyId is stored in the Session variable)
SendVerifyToken
verifies the code entered by the user matches the code sent to the user in the CreateVerify
call in Step1.aspx.cs
.
As before, there's a catch-block to handle errors such as an invalid token entered by the user. If there is an error, we show the same form again with the error.
If verification was successful, we render a simple confirmation page in Step3.aspx
:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Step3.aspx.cs" Inherits="Step3" %>
<p>You have successfully verified your phone number.</p>
To test the application, click on Step1.aspx
in the Solution Explorer. Then click on the green start button on the toolbar at the top.
You now have a running integration of MessageBird's Verify API using C#!
You can now leverage the flow, code snippets and UI examples from this tutorial to build your own two factor authentication system. Don't forget to download the code from the MessageBird Developer Guides GitHub repository.
Want to build something similar but not quite sure how to get started? Please feel free to let us know at support@messagebird.com, we'd love to help!