Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate unique random alphanumeric tokens in Golang?

Tags:

go

token

For a RESTful backend API, I want to generate unique url tokens to be used to authenticate users.

The unique data provided at registration to generate tokens are email addresses. But after generating tokens and sending that to the users, I don't need to decrypt received tokens to get email or other information. So the encryption can be one-way.

Initially I used bcrypt to do so:

func GenerateToken(email string) string {
    hash, err := bcrypt.GenerateFromPassword([]byte(email), bcrypt.DefaultCost)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Hash to store:", string(hash))

    return string(hash)

}

But since the tokens come as a url parameter (like /api/path/to/{token}) I can not use bcrypt because it generates tokens containing / like this:

"$2a$10$NebCQ8BD7xOa82nkzRGA9OEh./zhBOPcuV98vpOKBKK6ZTFuHtqlK"

which will break the routing.

So I'm wondering what is the best way to generate some unique 16-32 character alphanumeric tokens based on emails in Golang?

like image 950
Karlom Avatar asked Jul 23 '17 16:07

Karlom


1 Answers

As it was already mentioned you are doing it wrong and this is super insecure.

  1. Generate secure token using crypto package. This token completely random and not associated with any email.
func GenerateSecureToken(length int) string {
    b := make([]byte, length)
    if _, err := rand.Read(b); err != nil {
        return ""
    }
    return hex.EncodeToString(b)
}
  1. Create database table which maps this token to user identifier and during API request validate it.
like image 163
Andzej Maciusovic Avatar answered Nov 04 '22 02:11

Andzej Maciusovic