Skip to content
/ otp Public

One Time Password package for Go/Golang developers

License

Notifications You must be signed in to change notification settings

lucasbbb/otp

Repository files navigation

otp

One Time Password package for Go/Golang developers

Build Status codecov Go Report Card GoDoc Open Source Helpers Sourcegraph Release

中文文档

Contents

What is OTP

A one-time password (OTP) is an automatically generated numeric string that authenticates a user for a single transaction or login session.

The most important advantage addressed by OTPs is that, in contrast to static passwords, they are not vulnerable to replay attacks.

There are two kinds of OTP which are HOTP and TOTP. The vast majority of OTP today is TOTP. Very few people still use HTOP.

By the way, the TOTP RFC document has a mistake. More details can be found here if you are interested.

How to Use

Before using this package, you need to install Go and set your Go workspace first.

  1. Use the below Go command to install the package.
$ go get -u github.com/lucasbbb/otp
  1. Import it in your code.
import "github.com/lucasbbb/otp"
  1. Generate a Key and show it's QR code.
func main() {
    http.HandleFunc("/image", QRImage)
    _ = http.ListenAndServe(":6789", nil)
}

func QRImage(w http.ResponseWriter, req *http.Request) {
    secret, _ := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString("INEECT2TEBEVGICBEBGECRCEIVJA")
    key := otp.Key{
        Issuer:  "example",
        Account: "foo",
        Typ:     "totp",
        Secret:  secret,
    }
    image, _ := key.QRImage(256)
    _, _ = w.Write(image)
}
  1. User scan the QR code with Google Authenticator or other apps.

Google Authenticator

  1. Compare the code with the sever generated code.
func VerifyOTP(accountName, code string) {
	now := time.Now()
	// Get user's secret from DATABASE or other repository.
	// SELECT secret FORM user WHERE `account_name` = accountName
	secret, _ := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString("INEECT2TEBEVGICBEBGECRCEIVJA")
	res := otp.NewTOTP(secret).Validate(now, code)
	if res {
		// Continue your business logic.
	} else {
		// Abort.
	}
}