A Complete Step-by-Step Guide Using ASP.NET Core and Angular
Security is a critical part of any application. Passwords alone are no longer enough to protect user accounts because many users reuse passwords, pick weak ones, or get exposed through data leaks. Two-Factor Authentication (2FA) adds a powerful second layer of security, making unauthorized access significantly harder.
This article explains how to build a complete Two-Factor Authentication (2FA) system using:
ASP.NET Core Web API
SQL Server
Angular Frontend
Time-based One-Time Passwords (TOTP)
Google Authenticator / Microsoft Authenticator compatibility
We use simple language and provide full practical implementation.
What You Will Build
By the end of this tutorial, you will have:
A login system that requires both password + 2FA code
A QR code setup process for Google Authenticator
Backend that generates and validates TOTP codes
Database fields for storing 2FA secrets
Angular UI for enabling and verifying 2FA
A secure workflow similar to major applications (Google, GitHub, Microsoft)
Understanding Two-Factor Authentication (2FA)
2FA adds an extra security step after username and password:
User enters email and password
Backend verifies credentials
Backend checks if 2FA is enabled
If enabled → user must enter a 6-digit code
Code changes every 30 seconds
User gets code from an app like Google Authenticator
Backend verifies the code
User is authenticated
This prevents access even if the attacker knows the password.
Choosing the 2FA Method
This tutorial uses TOTP (Time-Based One-Time Password).
It is widely supported by:
Google Authenticator
Authy
Microsoft Authenticator
1Password
LastPass Authenticator
TOTP uses:
A shared secret key
The current timestamp
An algorithm to produce a 6-digit code
This code is valid for 30 seconds.
PART 1: Backend (ASP.NET Core)
Step 1: Install Required Package
We use Otp.NET library for generating TOTP codes.
dotnet add package Otp.NET
Step 2: Update User Model
Models/User.cs
public class User
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public bool TwoFactorEnabled { get; set; } = false;
public string TwoFactorSecretKey { get; set; }
}
Step 3: Generate Secret Key for User
When user enables 2FA:
using OtpNet;
public string Generate2FASecretKey()
{
var bytes = KeyGeneration.GenerateRandomKey(20);
return Base32Encoding.ToString(bytes);
}
Step 4: Create Endpoint to Enable 2FA
AuthController.cs
[Authorize]
[HttpPost("enable-2fa")]
public async Task<IActionResult> Enable2FA()
{
var userEmail = User.FindFirstValue(ClaimTypes.Email);
var user = await _context.Users.FirstOrDefaultAsync(u => u.Email == userEmail);
if (user == null)
return Unauthorized();
var secretKey = Generate2FASecretKey();
user.TwoFactorSecretKey = secretKey;
await _context.SaveChangesAsync();
var qrCodeUrl = $"otpauth://totp/{_config["App:Name"]}:{user.Email}?secret={secretKey}&issuer={_config["App:Name"]}&digits=6";
return Ok(new { SecretKey = secretKey, QrCodeUrl = qrCodeUrl });
}
The response returns:
SecretKey
QR code URL
Angular will convert QR code URL into an actual QR image.

Join the conversation! Your thoughts help the community grow.