为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕容森 2021-12-07 15:04:05
我想实现一个系统,在用户注册后,用户将收到一封电子邮件,其中包含一个链接以验证该电子邮件是否适用于该用户。我生成用于验证电子邮件的令牌的方式是这样的: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都是唯一的?实施该系统的常规方法是什么?请给我一些想法并告诉我这种生成令牌的方法是否好。
查看完整描述

2 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

查看https://pkg.go.dev/github.com/google/uuid#NewRandom

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


查看完整回答
反对 回复 2021-12-07
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

两点:

  • 不,所提供的方法不能保证它们是唯一的。

  • 您不需要让所有令牌都是唯一的。

为了扩展这些点......

您正在处理一组未完成的验证请求。那是:

  1. 用户提出请求;

  2. 您生成一个唯一的验证令牌并将其存储到某个现有数据库中。无论如何,这是验证工作所必需的。

  3. 用户收到您的电子邮件并单击其中包含您的令牌的链接。此时,您从持久存储中删除有关此未决验证请求的信息。

如您所见,在任何给定时间,您只有几个未完成的验证请求。因此,这种情况有两个重要的特性:

  • 您只需要这些未完成请求的令牌彼此不同。验证令牌可以与某些过去(或未来)请求的验证令牌相同。

  • 您的代币必须难以猜测(显然)。我相信你已经明白了。

因此,生成新令牌的方法如下:

  1. 产生一些难以猜测的东西。

  2. 将其与绑定到存储在您的存储中的未完成/未决验证请求的令牌进行比较。

    如果您发现具有相同标记的未完成请求,则说明发生了冲突,因此请转到步骤 (1) 并重复。

    否则令牌是好的,所以继续它并保留有关此请求的数据。

  3. 请求通过验证后,将其从您的存储中删除。

生成令牌的确切算法并不重要。我会说 UUID 或类似 SHA-256/512 的东西是根据一些随机数据计算出来的。


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信