Automate TOTP 2-Factor Authentication (2FA) with Playwright
Understanding 2FA Authenticator Apps and Time-based One-Time Passwords (TOTP)
2FA Login using TOTP: In an era where cybersecurity is paramount, two-factor authentication (2FA) has become a cornerstone of online security. Authenticator apps and Time-based One-Time Passwords (TOTP) offer an additional layer of protection beyond traditional password-based security measures. This guide aims to elucidate the concept of 2FA authenticator apps, delve into the workings of TOTP, and provide insights into their importance in digital security.
What are 2FA Authenticator Apps?
Authenticator apps generate time-based one-time passwords (TOTPs) on mobile devices for authentication. They serve as a secure means of implementing 2FA, requiring users to provide both something they know (their password) and something they have (their mobile device with the authenticator app installed).
How Do 2FA Authenticator Apps Work?
- Initialization: When setting up 2FA for an online account, users typically scan a QR code or manually enter a secret key provided by the service into their authenticator app.
- Code Generation: Once initialized, the authenticator app generates TOTPs based on a shared secret key and the current time. These TOTPs are typically six-digit codes that change every 30 seconds.
- Authentication: During login, users enter the current TOTP from their authenticator app along with their password. The service verifies the entered TOTP against the expected value based on the shared secret key.
Time-based One-Time Passwords (TOTP):
TOTP generates short-lived authentication codes using a shared secret key and the current time. The algorithm combines the secret key with the current time interval to produce a unique, one-time password that is valid only for a brief period, typically 30 seconds. TOTP ensures that even if an attacker intercepts a generated code, it quickly becomes obsolete, enhancing security.
Importance of Authenticator Apps and TOTP:
- Enhanced Security: Authenticator apps provide an additional layer of security beyond passwords, significantly reducing the risk of unauthorized access to online accounts.
- Protection Against Phishing: Because TOTP codes generate locally on your device and change with time, they resist phishing attacks that aim at stealing static passwords.
- Convenience: Authenticator apps offer a convenient and user-friendly method of implementing 2FA, eliminating the need to rely on SMS-based authentication methods that may be vulnerable to SIM swapping attacks.
Authenticator apps and Time-based One-Time Passwords (TOTP) play a crucial role in safeguarding online accounts against unauthorized access and cyber threats. By incorporating 2FA with authenticator apps into their security protocols, individuals and organizations can significantly enhance their digital security posture in an increasingly interconnected world.
Now we need to set up the Authenticator App:
Setup 2FA authenticator app
Use a phone app like 1Password, Authy, LastPass Authenticator, or Microsoft Authenticator, etc. to get 2FA codes when prompted during sign-in.
Scan the QR code.
Use an authenticator app from your phone to scan. If you are unable to scan, enter this text code instead.
The displayed QR code encodes the following information:
otpauth://totp/<DOMAIN>/issuer:<USERNAME>?secret=<SECRET>
This encoded URL includes:
- The protocol (otpauth) signals that an authenticator app should open this URL (DOMAIN).
- the type (totp)
- a label (USERNAME) that is a colon-separated combination of issuer and username
- a secret (SECRET)
- the issuer
The key element for logging in and automating the TOTP process is the supplied secret.
However, what’s the utilization method for this secret?
When you scan the QR code with an authenticator app, it combines the secret with the current time to create a unique password. The app then stores the second-factor secret, shows the issuer and username, and generates a new passcode every 30 seconds (though this time frame can be changed).That’s the gist of it!
You can then employ the passcode as a secondary login factor, providing assurance to services that it is indeed you are accessing your account.
Automating Login with Playwright for 2FA-Secured Websites
Automating the login process for websites secured with two-factor authentication (2FA) can streamline testing and administrative tasks. Playwright, a powerful automation library, provides the tools necessary to automate interactions with web pages, including those requiring 2FA.
Prerequisites:
- Install Node.js: Make sure Node.js is installed on your system. You can download it from nodejs.org.
- Set Up Playwright: Install Playwright using npm, the Node.js package manager, by running the following command in your terminal:
Steps to Automate Login with Playwright:
- Launch a Browser Instance:
import { chromium, Browser, Page } from 'playwright';
async function automateLogin(): Promise<void> {
const browser: Browser = await chromium.launch();
const context = await browser.newContext();
const page: Page = await context.newPage();
- Navigate to the Login Page:
// Navigate to login page
await page.goto('https://example.com/login');
- Enter Username and Password:
// Enter username and password
await page.fill('#username', 'your_username');
await page.fill('#password', 'your_password');
- Click on the Login Button:
// Click on the login button
await page.click('#loginButton');
- Handle 2FA Authentication:
Playwright supports interacting with elements on the page to handle 2FA. You can wait for the 2FA input field to appear and then fill it with the code.
// Handle 2FA authentication
async loginUserUI(childUser: User) {
let totp = new OTPAuth.TOTP({
issuer: "Issuer",
label: "LABLE",
algorithm: "SHA1",
digits: 6,
period: 30,
secret: "XXXXXXX",
});
}
The new OTPAuth.TOTP() syntax indicates that an instance of the TOTP class from the OTPAuth library is being created.
This instance is configured with various parameters such as issuer, label, algorithm, digits, period, and secret, which are used to generate and validate one-time passwords for authentication purposes.
In essence, new OTPAuth.TOTP() initializes a new TOTP (Time-based One-Time Password) object, allowing the application to generate OTPs for user authentication.
- Fill and Submit the 2FA code:
try
{
let token = totp.generate()
await this.authCode.fill(token, { timeout: 5000});
await this.submitAuthCode.click()
await this.waitFor(10000)
}
catch(err)
{
}
totp.generate() is a method call on the totp object. This method is provided by the OTPAuth library and is used to generate a one-time password (OTP) based on the TOTP algorithm.
The generate() method computes the current OTP value based on the TOTP parameters configured earlier, such as the secret key, time period, and algorithm. This OTP is typically used for user authentication purposes.
Once token holds the generated OTP, it can be used in the subsequent lines of code for filling an authentication code input field and submitting it for authentication.
Here’s the final code.
import * as OTPAuth from 'otpauth';
export class LoginPage {
readonly page: Page;
private readonly loginButton: Locator;
private readonly userNameInput: Locator;
private readonly passwordInput: Locator;
private readonly emailDisplay: Locator;
private userEmail: any;
private readonly authCode: Locator;
private readonly submitAuthCode: Locator;
constructor(page: Page) {
this.page = page;
this.loginButton = page.getByTestId(AppUniqueId.login_submitButton);
this.userNameInput = page.getByTestId(AppUniqueId.login_username);
this.passwordInput = page.getByTestId(AppUniqueId.login_password);
this.emailDisplay = page.getByTestId(AppUniqueId.personalDetails_email);
this.authCode = page.locator('#root > div > div > section > main > div > div > div > input');
this.submitAuthCode = page.locator('#root > div > div > section > main > div > div > button');
}
async waitFor(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async loginUserUI(childUser: User) {
let totp = new OTPAuth.TOTP({
issuer: "ISSUER",
label: "LABLE",
algorithm: "SHA1",
digits: 6,
period: 30,
secret: "XXXXXXXXXX”
});
await this.userNameInput.fill(await childUser.username);
await this.passwordInput.fill(await childUser.password);
await this.loginButton.click();
try{
let token = totp.generate()
await this.authCode.fill(token, { timeout: 5000});
await this.submitAuthCode.click()
}catch(err)
{
}
}
async verifyLoginUserEmail(childUser: User) {
this.userEmail = childUser.username;
try{
await this.page.locator("div[class='col-sm-12 d-flex impersonation-bar'] a").click()
}catch(err)
{
}
}
}
Conclusion:
Automating login for 2FA-secured websites using Playwright can enhance efficiency and productivity in various scenarios, from testing to administrative tasks. By following the steps outlined above, you can create robust automation scripts tailored to your specific requirements.
https://github.com/apurvakolse/playwright-typescript-totp
Feel free to customize and expand upon these steps to suit your needs and the specific requirements of the website you’re working with.
Disclaimer: Ensure that you have the necessary permissions to automate interactions with websites, and use this knowledge responsibly and ethically.
Click Here to read more blogs for Software Testing Tips and Practices.
Apurva is a Test Engineer, with 3+ years of experience in Manual and automation testing. Having hands-on experience in testing Web as well as Mobile applications in Selenium and Playwright BDD with Java. And loves to explore and learn new tools and technologies.