客户反馈“重置密码链接已过期”时,我第一反应不是把有效期改成 24 小时。刚收到就失效和真正超时是两类问题,延长有效期只会掩盖 Token 为什么对不上。
先只申请一次,然后保留原始链接
连续点击“忘记密码”会生成新的重置 Token,之前邮件里的链接随即失效。测试时只提交一次,等队列发出邮件后复制完整 URL,不要让邮箱安全扫描器截断参数。重点确认链接里是否同时带有客户标识、Token 和正确的网站域名。
可以在测试账号上对照数据库中的时间与 Token 字段,但不要把 Token 发到工单或群里。线上排查只记录是否变化、生成时间和客户 ID 即可。
SELECT entity_id, email, website_id,
rp_token_created_at,
CASE WHEN rp_token IS NULL THEN 'empty' ELSE 'set' END AS token_state
FROM customer_entity
WHERE email = 'test@example.com';
提交一次后刷新查询,如果 Token 很快又变化,说明有第二次请求、自动化脚本或客服后台操作覆盖了它。邮件发送延迟也会造成旧邮件晚于新邮件到达,客户点开的其实是已经被替换的那一封。
自定义邮件模板最容易丢参数
升级后沿用很老的模板时,不要凭记忆拼重置地址。先临时切回当前版本自带模板发一封测试邮件。如果默认模板可用,自定义模板不可用,问题就在变量或转义方式,而不是控制器。
还要检查配置作用域。多网站允许相同邮箱属于不同 website,生成 Token 的网站和打开链接的域名必须一致。反向代理把 Host 改错、邮件 Base URL 使用主站域名,也可能把客户带到另一套 website 上校验。
时间要比较数据库、PHP和应用节点
date -u
php -r 'echo gmdate("c"), PHP_EOL;'
mysql -e "SELECT UTC_TIMESTAMP(), NOW();"
Magento 保存的时间、PHP 默认时区和数据库会话时区如果混在一起,日志看着只差几分钟,校验时却可能已经超过配置窗口。先统一 UTC 基准,再检查后台 Password Recovery Link Expiration Period 的网站级配置。
修好后我会做两组验证:同一账号申请两次,确认第一封确实失效、第二封可用;不同 website 上的同邮箱各申请一次,确认链接只在所属站点生效。这样才能证明修的是 Token 流程,而不是碰巧让某一封邮件通过。

