You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django账户验证时check_token始终返回TRUE 二次点击链接未失效

问题根因

Django 内置的 PasswordResetTokenGenerator 生成 token 时,默认参与哈希计算的用户字段只有 password、last_login、is_active 三个。
你实现密码重置功能时,校验通过后会修改用户密码,密码哈希值发生变化,旧 token 自然校验失败;但账户验证逻辑里仅修改了 is_guest 字段,该字段不在默认的哈希因子范围内,修改后不会影响 token 校验结果,所以重复点击链接始终能通过校验。

解决方案

推荐自定义 Token 生成器,把 is_guest 字段加入哈希计算因子,步骤如下:

  1. 自定义继承自 PasswordResetTokenGenerator 的专属校验类
from django.contrib.auth.tokens import PasswordResetTokenGenerator

class AccountVerifyTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        # 加入is_guest字段参与哈希计算
        return f"{user.pk}{timestamp}{user.is_active}{user.password}{user.is_guest}"

# 实例化全局调用对象
account_verify_token_generator = AccountVerifyTokenGenerator()
  1. 替换序列化器中的校验逻辑
    将原有校验行:
if not PasswordResetTokenGenerator().check_token(user, token):

替换为:

if not account_verify_token_generator.check_token(user, token):

修改完成后,当你首次校验通过将 is_guest 改为 False 时,哈希值会发生变化,旧 token 后续校验都会返回 False,符合预期逻辑。

现有代码其他注意点

  • 你当前使用 UserAccount.objects.get(pk=uidb64) 查询用户,如果 uid 对应的用户不存在,会直接抛出 DoesNotExist 异常,不会走到后续 if user is None 的判断分支,建议改为捕获异常的写法,避免服务端报错:
try:
    user = UserAccount.objects.get(pk=uidb64)
except UserAccount.DoesNotExist:
    raise AuthenticationFailed('Invalid account. Please contact support')
  • 提示文案里的 contant 是拼写错误,正确拼写为 contact。

内容的提问来源于stack exchange,提问作者Luka Reeson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:21:04