Two Factor Authentication

Multi-factor authentication is an electronic authentication method in which a user is granted access to a website or application only after successfully presenting two or more pieces of evidence to an authentication mechanism: knowledge, possession, and inherence.

Source: Wikipedia

Implementation in Golang

To verify a specific user/device we need to assign it a unique secret key. Convert that secret key to base 32 encoding and build an otpauth:// URL.

// converting secret key to base32 encoding
secretBase32 := base32.StdEncoding.EncodeToString(secretKey)

issuer := "datumbrain.com"
account := "user4"

// creating otpauth url
authUrl := fmt.Sprintf("otpauth://totp/%s:%s?secret=%s&issuer=%s",
        url.PathEscape(issuer), url.PathEscape(account), secretBase32, issuer)
  • issuer in the above URL represents your application.
  • account represents the user in your application, it can be the user’s email, username, etc.

You can generate a QR code from this URL to scan with some mobile application like Google Authenticator.

Scan Code

QR Code

You can use some package like rsc.io/qr to generate a QR code from the above URL to scan with a mobile TOTP application.

// encoding url to qr code
qrCode, err := qr.Encode(authUrl, qr.Q)
if err != nil {
    panic(err)
}

// writing qr code to png file `/tmp/qr.png`
err = ioutil.WriteFile("/tmp/qr.png", qrCode.PNG(), 0600)
if err != nil {
    panic(err)
}

Authentication

Now when the user has configured their TOTP client and got their one-time password, you will need to verify it.

For this, there is a golang package github.com/dgryski/dgoogauth available on GitHub which may help you.

client := &dgoogauth.OTPConfig {
    Secret:      secretBase32,
}

isVerified, err := client.Authenticate(usersOtp)

The Authenticate() method will return an error when the OTP doesn’t have the correct format. It returns true if the OTP is correct or false otherwise.

Secured

Tell us what you think in comments below.