客户点击刚收到的重置密码邮件,却提示链接已过期或 Token 无效。不要立即把 Token Lifetime 调到几天:如果链接复制错误、网站范围不匹配或服务器时钟漂移,再长的有效期也不会解决。
检查邮件中的完整 URL
比较邮件源码和浏览器最终地址,确认 token、customer id/email 参数没有被换行、转义或营销跟踪系统截断。不要在日志和聊天中公开真实重置链接,它在有效期内等同于账号恢复凭据。
重复申请会让旧邮件失效
客户连续点击“忘记密码”,通常只应使用最新一封。邮件队列延迟会造成先申请的邮件后到达,看起来像“刚收到就失效”。记录申请时间、邮件发送时间和客户 reset_at/token 更新时间,避免只看收件箱顺序。
时间必须一致
date -u
mysql -e 'SELECT UTC_TIMESTAMP(), NOW();'
bin/magento config:show customer/password/reset_link_expiration_period
应用、数据库和主机应使用可靠时间同步。Magento 以存储时间和配置计算过期,显示时区可以不同,但不能有实际时钟偏差。容器暂停恢复后时间异常也要检查。
多网站账号范围
密码重置链接来自网站 A,客户却打开网站 B;若客户账号按 Website 共享范围隔离,系统可能找不到对应客户。邮件模板 Base URL、Store 参数和反向代理 host 必须属于发起请求的网站。
安全扫描器会不会消耗链接
某些邮件网关会自动访问链接做安全检查。正常 GET 预览不应直接完成重置,但定制模块若把验证或 token 清除放在首次访问,就会被扫描器提前触发。检查访问日志 user-agent 与时间,并把状态改变放到用户提交新密码的 POST。
修复后测试单次申请、连续两次申请、队列延迟、跨网站和链接预览。成功重置后旧 Token 必须失效,且日志不能暴露新密码或完整 Token。
数据库字段只能用于诊断
客户实体中的 rp_token 与 rp_token_created_at 可以帮助确认最新申请时间,但不要复制完整 token 到日志,也不要手工延长某个客户的时间戳。手工修改会绕过安全审计,且可能与缓存/账号锁定状态不一致。
邮件模板与编码
自定义模板若对 URL 再做一次 urlencode、HTML escape 或添加跟踪参数,token 中的特殊字符可能变化。查看最终 href 属性,而不是邮件可见文字;客户端自动把长 URL 换行时,点击与复制行为也可能不同。
安全回归
验证 token 只能使用一次、改密后现有会话是否按策略失效、旧密码不能登录、同一 IP 的申请有合理限速。错误提示不应泄露邮箱是否注册;客户收到邮件与攻击者枚举账号是两个需要同时处理的问题。
代理与 HTTPS 也可能改坏链接
反向代理没有正确传递 Host 或 HTTPS 状态时,邮件会生成内部域名、HTTP 地址或错误 Store 的 Base URL。浏览器随后被跳转到另一个网站,token 参数可能在跳转规则中丢失。检查代理头、secure base URL 和最终 Location 链,并确保 token 不进入第三方分析日志。

