Implementing Two-Factor Authentication (2FA) with TOTP in Golang
Tags: go, webdev, backend, coding
Published: 2023-07-22 08:50:43

## Introduction
In an era of increasing online security concerns, implementing robust authentication mechanisms is crucial. Two-Factor Authentication (2FA) provides an additional layer of security by requiring users to provide a second form of verification, typically a time-based one-time password (TOTP) or a HMAC-based one-time password (HOTP). In this blog post, we will explore how TOTP work and walk you through implementing 2FA using Golang.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d94aczgx4q7wc7s6rdij.png)

### TOTP (Time-Based One-Time Password)
Think of TOTP as a time-limited password that keeps changing every few seconds. When you set up 2FA on an application, it generates a secret key that is securely shared between the application and your device. Your device uses this key, combined with the current time, to generate a unique password that remains valid for a short period, typically 30 seconds. This password is entered along with your regular username and password to complete the login process. Popular applications like Google Authenticator use TOTP.

### Implementing 2FA with TOTP in Golang:
To implement 2FA with TOTP in Golang, we will use the `github.com/xlzd/gotp` library, which simplifies the process. Let's break down the steps:

- __Generating a new TOTP key__
When you enable 2FA on an application, it generates a secret key. This key is shared securely between the application and your device.

- __Generating a TOTP code__:
To generate a TOTP code, your device combines the shared key with the current time and generates a unique password. This password remains valid for a short period, usually 30 seconds.

- __Validating a TOTP code__:
When you log in using 2FA, the application expects you to enter the correct TOTP code. The server uses the same shared key and checks if the code you provided matches the one generated on your device. If they match, you are granted access.

#### To better understand the process, let's go through a practical example with Golang
```golang
package main

import (
	"fmt"
	"time"

	"github.com/skip2/go-qrcode"
	"github.com/xlzd/gotp"
)

func main() {
	randomSecret := gotp.RandomSecret(16)
	fmt.Println("Random secret:", randomSecret)
	generateTOTPWithSecret(randomSecret)
	testOTPVerify(randomSecret)
}

func generateTOTPWithSecret(randomSecret string) {
	totp := gotp.NewDefaultTOTP(randomSecret)
	fmt.Println("current one-time password is:", totp.Now())

	uri := totp.ProvisioningUri("user@email.com", "myApp")
	fmt.Println(uri)

	qrcode.WriteFile(uri, qrcode.Medium, 256, "qr.png")
}

func testOTPVerify(randomSecret string) {
	totp := gotp.NewDefaultTOTP(randomSecret)
	otpValue := totp.Now()
	fmt.Println("current one-time password is:", otpValue)

	ok := totp.Verify(otpValue, time.Now().Unix())
	fmt.Println("verify OTP success:", ok)
}
```
In the above code, we first generate a random secret key using the `gotp.RandomSecret` function. Then, we demonstrate how to generate a TOTP and display it, along with the QR code provisioning URI. The provisioning URI can be scanned by a mobile authenticator app (e.g., Google Authenticator) to set up the 2FA. 
The `testOTPVerify` function shows how to verify the TOTP with the current time.

By running this code, you'll experience the dynamic TOTP generation, which changes every few seconds, providing an extra layer of security for your application.

## Conclusion
Implementing Two-Factor Authentication (2FA) adds an extra layer of security to your applications. In this blog post, we explored how TOTP work and provided non-technical explanations to help you understand the concepts. We also provided example code and walked you through implementing 2FA using Golang, using the `github.com/xlzd/gotp` library.