Django 的签名模块允许在不进行用户登录或会话验证的情况下实现安全的退订链接。直接在 URL 中使用用户 ID 的不安全做法容易遭受批量退订攻击。将随机令牌存储在数据库中是一种常见但更复杂的解决方案。Django 的 django.core.signing 模块通过用 SECRET_KEY 对值(如用户主键)进行签名,提供无需数据库存储即可实现的防篡改令牌。“盐值”(salt)至关重要,可防止不同功能之间的令牌发生碰撞,确保某一用途(例如公告)的令牌无法被用于另一用途(例如论坛通知)。尽管令牌经过签名,但它们并非机密;其中的数据可读,但无法在不使签名无效的情况下被篡改。因此,切勿对需要保密的信息进行签名。至关重要的是,退订操作应通过 POST 请求执行,而非 GET 请求,以防止邮件扫描器和预取器意外导致用户退订。推荐的工作流程是:先通过 GET 请求显示确认页面,随后通过 POST 请求完成最终操作。退订令牌通常不需要设置过期时间,因为重复点击旧链接会产生相同的安全结果。然而,对于魔法登录链接等敏感操作,signing.loads 中的 max_age 参数可在无需数据库存储的情况下实现过期机制。对于单次使用令牌场景(如邮箱验证),由于签名本身无法追踪使用情况,因此需要额外的状态管理(例如数据库中记录已使用的令牌)。
django.core.signing模块通过用SECRET_KEY对值(如用户主键)进行签名,提供无需数据库存储即可实现的防篡改令牌。“盐值”(salt)至关重要,可防止不同功能之间的令牌发生碰撞,确保某一用途(例如公告)的令牌无法被用于另一用途(例如论坛通知)。尽管令牌经过签名,但它们并非机密;其中的数据可读,但无法在不使签名无效的情况下被篡改。因此,切勿对需要保密的信息进行签名。至关重要的是,退订操作应通过 POST 请求执行,而非 GET 请求,以防止邮件扫描器和预取器意外导致用户退订。推荐的工作流程是:先通过 GET 请求显示确认页面,随后通过 POST 请求完成最终操作。退订令牌通常不需要设置过期时间,因为重复点击旧链接会产生相同的安全结果。然而,对于魔法登录链接等敏感操作,signing.loads中的max_age参数可在无需数据库存储的情况下实现过期机制。对于单次使用令牌场景(如邮箱验证),由于签名本身无法追踪使用情况,因此需要额外的状态管理(例如数据库中记录已使用的令牌)。