网站邮件验证系统异常:Hotmail打开邮件自动触发验证链接
兄弟,这个坑我之前也踩过!问题出在Hotmail(现在叫Outlook.com)的邮件内容预加载机制,不是你的代码bug,是邮件客户端的"自作主张"。
为什么会自动验证?
你的验证流程是把验证链接直接指向signinup.php,并通过URL参数传递email和token。而Hotmail为了给用户生成邮件预览、检测链接安全性,会自动用爬虫访问邮件里的所有链接——相当于它替你"点"了一下验证链接。
再看你的代码逻辑:
if (!empty($_SERVER["QUERY_STRING"])) { parse_str($_SERVER["QUERY_STRING"]); // 连接数据库,匹配token和时间 if ($result["token"] && $result["token"] === $token && $result["entry_time"] > time() - 600) { // 迁移数据到已验证数据库 } }
这段代码只要收到合法的email和token参数,不管请求是来自用户的浏览器,还是Hotmail的爬虫,都会直接执行数据迁移。所以Hotmail的预加载请求满足条件后,就自动把用户标记为已验证了。
怎么解决?
给验证流程加一道"人工确认"的门槛,让爬虫无法触发最终的迁移操作:
方案1:增加手动确认按钮
把验证链接指向一个展示页面(比如verify_email.php),页面上显示"请点击下方按钮完成邮箱验证",然后通过POST请求触发真正的迁移逻辑。这样Hotmail的爬虫只会GET请求打开页面,不会触发POST操作,只有用户手动点击按钮才会完成验证。方案2:检查请求的交互特征
比如判断请求是否来自浏览器:可以检查User-Agent是否包含邮件客户端爬虫的标识(比如Hotmail的预览爬虫UA会有Microsoft Outlook相关字样),但UA可能会变,不如方案1可靠。或者要求请求必须携带Referer头(但部分浏览器会禁用Referer,可能误伤用户)。方案3:修改验证接口的请求方式
把验证逻辑从GET请求改为POST请求,验证链接指向的页面让用户提交一个表单(可以自动提交,但需要JS触发,爬虫一般不执行JS),这样只有用户在浏览器打开页面并执行JS,才会发送POST请求完成验证。
额外建议
以后做邮件验证,尽量不要用GET请求直接执行敏感操作(比如数据迁移、状态变更),GET请求很容易被爬虫、预加载、甚至误触触发,用POST或者需要用户交互的方式更安全。
内容的提问来源于stack exchange,提问作者oldboy

