logo logo

Overcoming API Testing Challenges Using Postman: One-Time Password 2FA

KeyPass

Traditionally, access to online services was protected (typically) only by a username and a password. This type of authentication can be described as a Single-Factor Authentication (SFA), since it involves only one authentication factor, called knowledge. The SFA has a serious flaw 😲 Anyone with knowledge of a username and password can access protected account / online service. The solution for this weakness appears in the form of additional authentication factors, like a possession. Combined with the knowledge factor, the possession factor forms a Two-Factor Authentication (2FA). In order to authenticate oneself, the user has to provide not only a username and a password but also additional passcode that is changing through time, which is known as the OTPOne-Time Password.

There are two most commonly used implementations of 2FA

  1. Sending OTP to the user’s mobile phone number via SMS.
  2. Generating OTP via authenticator app installed on the user’s phone (the focus of this article).

The challenge is simple – Automate an API test case that requires a one-time password (OTP) generated by the authenticator app installed on a mobile phone (e.g. Google Authenticator, Authy). The very purpose of this article is to demonstrate how this can be achieved using Postman as an API testing tool and GitHub API.

The first encounter with this challenge could bring misconceptions common for beginners:

  • One-time password can’t be automated;
  • The authenticator app needs access to the internet in order to generate code;
  • The authenticator app has to be installed on a cellphone.

Fortunately, all these statements are incorrect 😜
Let’s get started!


Table of Content

  1. Understanding TOTP-based 2FA
  2. Learning by doing: A Step-by-Step Guide on How to Automate the API Test
    • Step 1: Prepare the environment
    • Step 2: Start with a simple API request and a manual API test
    • Step 3: Automate!

Understanding TOTP-based 2FA

TOTP is an acronym that stands for a Time-based One-Time Password. This value is dynamic, as it usually lasts for 30 seconds and contains a six-digits. TOTP can be calculated based on a shared secret key and the current time of the day (that is where the “time-based” part comes from) using an algorithm described as an open standard in RFC6238 document. This means, if you have access to the secret key, you can calculate the OTP value on your own, independently of any authenticator app and mobile phone, using a programming language of your choice. 

There is no need to reinvent the wheel because you can find the solutions that have already been baked on the web 👨‍🍳. For example, if you are using Ruby programming language, you can calculate TOTP using rotp gem. To achieve the same in the TestProject testing tool, there is an addon described in the following article. Since we are using Postman, it is convenient to use JavaScript – You can find the script written by Pietr Stapp Here. In the text below you will find a demonstration on how this script can be used to automate the time-based one-time password.

Learning by doing: A Step-by-Step Guide on How to Automate the API Test

Our test is simple: We just want to assert that a GET request sent to https://api.github.com/user/repos endpoint will be successful, resulting in a status code 200 OK in the response.

STEP 1: Prepare the environment

  1. To follow this guide, you will need a GitHub account and Postman installed on your machine. 
  2. Sign in to you your GitHub account and navigate to the security page.
  3. Enable the two-factor authentication by using any TOTP mobile app (like Authy or Google authenticator) and copy the two-factor secret along the way (we will need it later). To obtain the two-factor secret, you will need to click on “enter this text code instead” link in the second step of this process. You can find more detailed instructions on how to achieve this on GitHub help pages

One-Time-Password_two-factor secret

  1. To make sure that TOTP-based 2FA is now enabled on your GitHub account, sign out and then sign in again. If you have done it right, you will be asked for the authentication code after entering the username and the password. This also means that the API access to your account will be restricted by 2FA.

 

STEP 2: Start with a simple API request and a manual API test

  1. Open the Postman app and create a new request by clicking on “+” button.
  2.  To retrieve the list of your repositories, you will need to send a GET request to https://api.github.com/user/repos.
  3. Click on the “Test” tab. On the right side, you will see the list of available code snippets.
  4. Choose the “Status code: Code is 200” snippet, to add the test. 

API Testing Challenges_Postman

  1. Click on the “Send” button – this will execute the API call. The status code in the response is “401 Unauthorized” and our test failed. In other words, GitHub doesn’t know who you are. As a result of this, it can’t retrieve your repositories. To fix this, you need to provide credentials.

API Testing Challenges_Provide Credentials

  1. Click on “Authorization tab“, then in “Type” dropdown choose “Basic Auth”, and, finally, enter your GitHub username and password.

API Testing Challenges_GitHub username and password

  1. Click on the “Send” button again. The Test failed again, but this time, the response is different: “Must specify two-factor authentication OTP code.”. You can find this code on your authenticator app, but in which way should it be provided? You can find the answer to this question if you check response headers. “X-GitHub-OTP” header is required and we can send OTP code simply by using it. 

One-Time-Password_X-GitHub-OTP

  1. Click on “Headers” tab in the request section of Postman interface (like in the screenshot below). 
  2. Add new header – “X-GitHub-OTP” as a key and 6-digits OTP code from your mobile app as a value.
  3. Click on the “Send” button.

One-Time-Password_Send_Button

If you check the “Test Results” tab, you will see that the test was finally successful!👏🏻 In my case, body response contains only an empty array (“[ ]”), because I don’t have any repositories. 

We have executed only the manual test so far, in the final step we want to automate it using collection runner.

 

STEP 3: Automate!

  1. Click on the “New collection” button under the “Collections” tab on the left side of Postman interface. Collections can be described as reusable test suites that can contain one or more API requests and tests. 
  2. Insert a name for your new collection (e.g. “GitHub Web API”). 
  3. Click on the “Pre-request Scripts” tab and paste the script for generating OTP code that can be found on this page. Any JavaScript code placed here will be executed before every single request in the collection. In this dialog. 
  4. After you have pasted the code, scroll to the bottom of the page and replace YOUR_SECRET_HERE string between quotation marks with the secret 2fa key that you have obtained earlier.  
  5. Click on the “Create” button in the bottom right corner of the dialog.

API Testing Challenges_Create a new collection

Take a look at the last line of the code in the pre-request script – You can see that TOTP value is stored into an environment variable named “OTP”. In Postman, variable is used by putting the name of the variable between double curly braces, e.g. {{OTP}}. Notice that we didn’t create any environment yet. Also, we have created the collection, but our request is not a part of it. We will resolve all these issues in the following steps.

  1. In the request section of Postman dialog, right next to the “Send” button, there is a “Save” button – click on it. “Save request” dialog will be opened up. 
  2. Select previously created collection and save the request.

Request_Section

 

  1. Get back to the request, and click on the “Headers” tab. Replace six-digit value with {{OTP}} variable.

One-Time-Password_Variable

 If you hover over the variable, you will see an interesting warning: “Unresolved variable”. The warning is a result of missing variable definition. We need to add an environment and to declare OTP variable.

  1. To add a new environment, simply click on the “eye” icon in the top right corner of the Postman user interface.

AddNewEnvironment

 

  1.  Click on the “Add” button next to the “Environment” label, on the top of the dialog.

Environment_Label

  1. Type in a label for a new environment (e.g. GitHub Web API). Add “OTP” as a variable and any value in the “current value” field. This value will be replaced automatically by the pre-request script. Click on the “Add” button and then close the dialog.

One-Time-Password_Current_Value

  1. To start Collection Runner, simply locate the collection under the “Collections” tab on the left side of Postman and you will see an arrow-like button. Click on it and then click on the “Run” button.

Run_Button

  1. The Collection Runner will be opened in a new window. Make sure that the appropriate environment is selected, and then click on the “Run” button at the bottom.

Run_GitHub_Web

  1. Lastly, our test is executed automatically! 🎉

Share in the comments below how would YOU
overcome use cases with a one-time password 2FA? 🤔

About the author

Darko Zivkovic

QA engineer interested in everything related to software testing. Cyclist. Runner. Feel free to connect with me on LinkedIn.

Leave a Reply

FacebookLinkedInTwitterEmail