使用MX记录验证电子邮件地址

时间:2009-12-29 20:16:30

标签: php email-validation mx-record

情境:
我的网络应用程序上有一个联系表单,它有很多垃圾邮件 我正在松散地验证电子邮件地址的格式,即^.+@.+\..+$
我使用的是垃圾邮件过滤服务(defensio),但返回的垃圾邮件分数与有效邮件重叠。在0.4的阈值处,一些垃圾邮件通过,一些客户的问题被错误地抛入日志中并显示错误。

所有垃圾邮件都使用虚假的电子邮件地址,例如: zxmzxm@ywduasm.com

美国的专用PHP5 Linux服务器,mysql,仅记录垃圾邮件,通过电子邮件发送非垃圾邮件(未存储)。

提案: 使用php的checkdnsrr(preg_replace(/^.+?@/, '', $_POST['email']), 'MX')检查电子邮件域解析为有效地址,登录到文件,然后重定向并显示无法解析的邮件的错误,像以前一样继续使用垃圾邮件过滤服务解析根据checkdnsrr()

我已经读过(我自己也对此持怀疑态度),你永远不应该将这种类型的验证留给远程查找,但为什么呢?

除了连接问题,无论如何我会遇到比联系表格更大的问题,checkdnsrr会遇到误报/否定吗?
是否会有一些不会解决的地址类型? gov地址? ip电子邮件地址?
我是否需要转义传递给checkdnsrr()的主机名?

解决方案: 所有三个答案的组合(希望我能接受不止一个作为复合答案)。

我正在使用:

$email_domain = preg_replace('/^.+?@/', '', $email).'.';
if(!checkdnsrr($email_domain, 'MX') && !checkdnsrr($email_domain, 'A')){
   //validation error
}

正在记录和轮换所有垃圾邮件。 以期在以后升级到作业队列。

有人评论要求邮件服务器让用户验证,我觉得这会有太多的流量,可能会让我的服务器被禁止或以某种方式遇到麻烦,这只是为了删除大部分电子邮件因服务器地址无效而被退回的情况。

http://en.wikipedia.org/wiki/Fqdn

RFC2821
The lookup first attempts to locate an MX record associated with the name.
If a CNAME record is found instead, the resulting name is processed as if 
it were the initial name.
If no MX records are found, but an A RR is found, the A RR is treated as
if it was associated with an implicit MX RR, with a preference of 0,
pointing to that host.  If one or more MX RRs are found for a given
name, SMTP systems MUST NOT utilize any A RRs associated with that
name unless they are located using the MX RRs; the "implicit MX" rule
above applies only if there are no MX records present.  If MX records
are present, but none of them are usable, this situation MUST be
reported as an error.

非常感谢所有人(尤其是ZoogieZork的A记录后备提示)

5 个答案:

答案 0 :(得分:5)

我认为使用checkdnsrr()进行MX查找没有什么害处,我也看不出可能出现误报。你不需要转义主机名,事实上你可以使用这种技术并通过与MTA交谈并测试用户是否存在于给定主机来进一步使用它(但是这种技术可能并且可能会让你有些错误一些主持人的积极因素。)

答案 1 :(得分:5)

DNS查找有时会很慢,具体取决于网络流量和数据。拥堵,所以这是需要注意的事情。

如果我在你的鞋子里,我会测试它,看看它是怎么回事。大约一周左右,将所有电子邮件记录到数据库或日志文件中,并包含一个字段,以指示是否将其标记为垃圾邮件或合法电子邮件。一周结束后,看看结果,看看它是否正如您所期望的那样表现。

采用这种日志记录/测试方法,您可以灵活地进行测试,而不必担心丢失客户电子邮件。

我已经养成了为CSS隐藏的表单添加额外字段的习惯,如果已经填写,我认为它是由垃圾邮件机器人提交的。我还确保使用像“url”或“website_url”这样的名称,这些名称看起来像垃圾邮件机器人的合法字段名称。为字段添加标签,上面写着“请勿填写此字段”,这样如果某人的浏览器无法正确呈现,他们就会知道不填写垃圾邮件字段。到目前为止,它对我来说非常好。

答案 2 :(得分:2)

function mxrecordValidate($email){
        list($user, $domain) = explode('@', $email);
        $arr= dns_get_record($domain,DNS_MX);
        if($arr[0]['host']==$domain&&!empty($arr[0]['target'])){
                return $arr[0]['target'];
        }
}
$email= 'user@radiffmail.com';

if(mxrecordValidate($email)) {
        echo('This MX records exists; I will accept this email as valid.');
}
else {
        echo('No MX record exists;  Invalid email.');
}

答案 3 :(得分:0)

MX Lookup只是图片的一部分,如果您想确保电子邮件地址本身有效,那么您需要尝试向该帐户发送电子邮件。

另一种可能的情况是,无论如何,有人可能只是使用被入侵的机器上的被劫持的电子邮件帐户。当然,这可能不太可能发生,但它仍然存在。

有电子邮件地址验证库可以执行此操作,只需搜索电子邮件验证。

所有这些都可以异步完成。我在我的网站上进行了此设置,在这种情况下,电子邮件将保存在数据库中(用于审计目的),作业排队,然后当作业到来执行时,将在该时间点执行任何其他验证。它将繁重的工作卸载到另一个线程。

对于用户来说,好像电子邮件已经发送,它是(它在数据库中),并且可以在内部查看,但实际的电子邮件将不会被邮寄,直到该作业执行,这可以立即或一些设定的时间,具体取决于服务器负载。

沃尔特

答案 4 :(得分:0)

//The Code *https://davidwalsh.name/php-email-validator*  
function domain_exists($email, $record = 'MX'){
    list($user, $domain) = split('@', $email);
    return checkdnsrr($domain, $record);
}

if(domain_exists('user@davidwalsh.name')) {
    echo('This MX records exists; I will accept this email as valid.');
} else {
    echo('No MX record exists;  Invalid email.');
}