猿问

如何生成唯一的令牌(用于电子邮件验证)?

我想实现一个系统,在用户注册后,用户将收到一封电子邮件,其中包含一个链接以验证该电子邮件是否适用于该用户。


我生成用于验证电子邮件的令牌的方式是这样的:


import (

    "crypto/rand"

    "encoding/base64"

)


func generateToken() (string, error) {

    b := make([]byte, 35)

    _, err := rand.Read(b)

    if err != nil {

        return "", err

    }

    return base64.URLEncoding.EncodeToString(b), nil

}

但是我想问的是这个方法行不行?如何让这个方法生成的所有token都是唯一的?


实施该系统的常规方法是什么?


请给我一些想法并告诉我这种生成令牌的方法是否好。


慕容森
浏览 174回答 2
2回答

吃鸡游戏

查看https://pkg.go.dev/github.com/google/uuid#NewRandom。您可能需要考虑将其与电子邮件地址和到期日期/时间一起存储在数据库中,以便验证不会永远留在那里。您可能只想允许人们在 24 小时或 7 天等内进行验证。有另一份工作,定期清理过期和未经验证的电子邮件。

一只斗牛犬

两点:不,所提供的方法不能保证它们是唯一的。您不需要让所有令牌都是唯一的。为了扩展这些点......您正在处理一组未完成的验证请求。那是:用户提出请求;您生成一个唯一的验证令牌并将其存储到某个现有数据库中。无论如何,这是验证工作所必需的。用户收到您的电子邮件并单击其中包含您的令牌的链接。此时,您从持久存储中删除有关此未决验证请求的信息。如您所见,在任何给定时间,您只有几个未完成的验证请求。因此,这种情况有两个重要的特性:您只需要这些未完成请求的令牌彼此不同。验证令牌可以与某些过去(或未来)请求的验证令牌相同。您的代币必须难以猜测(显然)。我相信你已经明白了。因此,生成新令牌的方法如下:产生一些难以猜测的东西。将其与绑定到存储在您的存储中的未完成/未决验证请求的令牌进行比较。如果您发现具有相同标记的未完成请求,则说明发生了冲突,因此请转到步骤 (1) 并重复。否则令牌是好的,所以继续它并保留有关此请求的数据。请求通过验证后,将其从您的存储中删除。生成令牌的确切算法并不重要。我会说 UUID 或类似 SHA-256/512 的东西是根据一些随机数据计算出来的。
随时随地看视频慕课网APP

相关分类

Go
我要回答