default_token_generator 如何存储令牌?

How does default_token_generator store tokens?

最近使用教程搭建了一个基于Django的认证系统。在这个系统中,我在 forms.py 中创建了一个令牌。然后在激活激活邮件中发送此令牌(作为 link)。

from django.contrib.auth.tokens import default_token_generator    
token = default_token_generator.make_token(user)

接收 get 请求的视图与此 link 中提供的令牌和用户 ID 相匹配,并使用以下方法检查令牌:

default_token_generator.check_token(user, token)

这验证了令牌是通过我的站点发送的。但是我不明白这个过程。令牌是唯一的,但我似乎没有将令牌保存在某个地方?那么check_token()如何验证令牌?

令牌由时间戳和 HMAC 值组成。 HMAC 是一个带键的散列函数:散列使用一个秘密密钥(默认settings.SECRET_KEY)来获得一个唯一的值,但是"unhashing"无论有没有密钥都是不可能的。

哈希组合了四个值:

  • 用户的主键。
  • 用户的散列密码。
  • 用户上次登录时间戳。
  • 当前时间戳。

令牌然后由当前时间戳和这四个值的哈希值组成。前三个值已经在数据库中,第四个值是token的一部分,所以Django可以随时验证token。

通过在哈希中包含用户的哈希密码和上次登录时间戳,当用户登录或更改密码时,令牌会自动失效。还检查当前时间戳以查看令牌是否已过期。请注意,即使当前时间戳包含在令牌中(作为 base36 编码的字符串),如果攻击者更改了值,哈希值也会更改并且令牌会被拒绝。