邮件里的免密登录链接在电脑上点能进,转发到手机上打开就提示令牌无效,同一个链接十分钟内有效,用户以为链接坏了。乍看像缓存或者权限的锅,追下去往往不是。

$token = hash_hmac('sha256', $uid . '|' . $exp, AUTH_SALT);
set_transient('magic_' . $token, $uid, 600);
// 校验只比对 token 与过期时间,不看 User-Agent

追下去是这么回事:令牌签发时把 User-Agent 的哈希一起存了进去,校验时比对不一致就判无效。邮件客户端打开链接时的 UA 和浏览器点开时也不一样,扫描器一碰同样会失败。

碰到「免密登录设备绑定」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

具体做法是,免密令牌只绑用户和过期时间,不绑 UA 这类会变的特征;确实要做设备限制,用首次使用时绑定的设备 ID,别用 UA 哈希;令牌一次有效,用掉后立刻置为已使用;在电脑和手机各点一次同一封邮件,确认两边行为一致。

验收就看一点,同一封邮件在手机和电脑上都能登录一次,第二次点提示链接已使用。

作者 9823189