如何在不发送电子邮件的情况下检查电子邮件地址是否存在

时间:2009-02-19 14:20:43

标签: php email smtp telnet email-validation

我遇到了PHP code to check email address using SMTP without sending an email

有没有人尝试过类似的东西或者它对你有用吗?你能说出一个电子邮件客户/用户输入是否正确&存在?

14 个答案:

答案 0 :(得分:84)

您可以有时使用两种方法来确定收件人是否确实存在:

  1. 您可以连接到服务器,然后发出VRFY命令。很少有服务器支持此命令,但它仅用于此目的。如果服务器以2.0.0 DSN响应,则该用户存在。

    VRFY用户

  2. 您可以发出RCPT,并查看邮件是否被拒绝。

    MAIL FROM:<>

    RCPT TO:< user @ domain>

  3. 如果用户不存在,您将获得5.1.1 DSN。但是,仅仅因为电子邮件未被拒绝,并不意味着用户存在。某些服务器将默默地丢弃此类请求,以防止枚举其用户。其他服务器无法验证用户,无论如何都必须接受该消息。

    还有一种称为灰名单的反垃圾邮件技术,它会导致服务器最初拒绝该地址,期望真正的SMTP服务器稍后会尝试重新传递。这将破坏验证地址的尝试。

    老实说,如果您尝试验证地址,最好的方法是使用简单的正则表达式来阻止显然无效的地址,然后将带有链接的实际电子邮件发送回您的系统,以验证收到的电子邮件。这也确保了用户输入了他们的实际电子邮件,而不是恰好属于其他人的轻微拼写错误。

答案 1 :(得分:45)

这里的其他答案讨论了尝试这样做的各种问题。我想我会告诉你如何尝试这个,以防你想通过自己学习来学习。

您可以通过telnet连接到邮件服务器,询问是否存在电子邮件地址。以下是测试stackoverflow.com的电子邮件地址的示例:

C:\>nslookup -q=mx stackoverflow.com
Non-authoritative answer:
stackoverflow.com       MX preference = 40, mail exchanger = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackoverflow.com       MX preference = 10, mail exchanger = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackoverflow.com       MX preference = 20, mail exchanger = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackoverflow.com       MX preference = 30, mail exchanger = STACKOVERFLOW.COM.S9B1.PSMTP.com

C:\>telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 ready.  CA Business and Professions Code Section 17538.45 forbids use of this system for unsolicited electronic mail advertisements.

helo hi
250 Postini says hello back

mail from: <me@myhost.com>
250 Ok

rcpt to: <fake@stackoverflow.com>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 w41si3198459wfd.71

以数字代码为前缀的行是来自SMTP服务器的响应。我添加了一些空行以使其更具可读性。

许多邮件服务器不会将此信息作为防止垃圾邮件发送者收集电子邮件地址的方法返回,因此您不能依赖此技术。但是,通过检测无效的邮件服务器或者如上所述拒绝收件人地址,您可能会成功清除一些明显不良的电子邮件地址。

另请注意,如果您对它们提出过多请求,邮件服务器可能会将您列入黑名单。


在PHP中,我相信您可以使用fsockopenfwritefread以编程方式执行上述步骤:

$smtp_server = fsockopen("STACKOVERFLOW.COM.S9A1.PSMTP.com", 25, $errno, $errstr, 30);
fwrite($smtp_server, "helo hi\r\n");
fwrite($smtp_server, "mail from: <me@myhost.com>\r\n");
fwrite($smtp_server, "rcpt to: <fake@stackoverflow.com>\r\n");

答案 2 :(得分:8)

一般的答案是,如果您向其发送电子邮件,您可以检查电子邮件地址是否存在事件:它可能会陷入黑洞。

据说那里描述的方法非常有效。它在ZoneCheck的生产代码中使用,除了它使用RSET而不是QUIT。

如果用户与他的邮箱的互动并不过分,许多网站实际上会通过发送必须发送回发射器的密码来测试邮件是否到达某处(通过发送到秘密URL或通过电子邮件发回这个密码)。大多数邮件列表都是这样的。

答案 3 :(得分:6)

不是......某些服务器可能无法检查“rcpt to:”

http://www.freesoft.org/CIE/RFC/1123/92.htm

这样做会带来安全隐患......

如果服务器这样做,您可以编写机器人来发现服务器上的每个地址....

答案 4 :(得分:5)

当目标邮件服务器使用灰名单时,这将失败(在其他情况下)。

灰名单:SMTP服务器在以前未知的客户端第一次连接时拒绝发送,允许下次使用;这样可以保留一定比例的垃圾邮件,同时允许合法使用 - ,因为预计合法邮件发件人将重试,这是普通邮件传输代理将要执行的操作。

但是,如果您的代码仅检查服务器一次,则具有灰名单的服务器将拒绝传递(因为您的客户端是第一次连接);除非您在一段时间内再次检查,否则您可能会错误地拒绝有效的电子邮件地址。

答案 5 :(得分:4)

一些问题:

  1. 我确定如果您提供的地址不存在,某些SMTP服务器会立即通知您,但有些服务器不会作为隐私措施。他们只会接受你给他们的任何地址,并默默地忽略那些不存在的地址。
  2. 正如文章所说,如果您经常使用某些服务器执行此操作,他们会将您列入黑名单。
  3. 对于某些SMTP服务器(如gmail),您需要使用SSL才能执行任何操作。 仅当使用gmail的SMTP服务器发送电子邮件。

答案 6 :(得分:3)

function EmailValidation($email)
{
    $email = htmlspecialchars(stripslashes(strip_tags($email))); //parse unnecessary characters to prevent exploits
    if (eregi('[a-z||0-9]@[a-z||0-9].[a-z]', $email)) {
        //checks to make sure the email address is in a valid format
        $domain = explode( "@", $email ); //get the domain name
        if (@fsockopen ($domain[1],80,$errno,$errstr,3)) {
            //if the connection can be established, the email address is probably valid
            echo "Domain Name is valid ";
            return true;
        } else {
            echo "Con not a email domian";
            return false; //if a connection cannot be established return false
        }
        return false; //if email address is an invalid format return false
    }
}

答案 7 :(得分:2)

“你能说出一个电子邮件客户/用户输入是否正确且存在吗?”

实际上这些是两个不同的东西。它可能存在但可能不正确。

有时您必须使用面值的用户输入。否则,有很多方法可以打败这个系统。

答案 8 :(得分:2)

关于您所能做的就是搜索DNS并确保电子邮件地址中的域名有MX记录,除此之外没有可靠的处理方法。

某些服务器可能与您与SMTP服务器通信的rcpt-to方法一起使用,但它完全取决于服务器的配置。另一个问题可能是重载服务器可能会返回550代码,说用户未知,但这是一个临时错误,有一个永久性错误(我认为是451?)可以返回。这完全取决于服务器配置的

我个人会检查DNS MX记录,然后在MX记录存在的情况下发送电子邮件验证。

答案 9 :(得分:2)

虽然这个问题有点陈旧,但此服务提示可能会帮助用户搜索类似的解决方案,在发送之前检查电子邮件地址,而不是语法验证。

我一直在使用此open sourced service来更深入地验证电子邮件(检查电子邮件地址域中的mx记录等),以获得一些效果良好的项目。它还检查常见的拼写错误是非常有用的。演示here

答案 10 :(得分:1)

假设它是用户的地址,某些邮件服务器确实允许SMTP VRFY命令实际验证其邮箱的电子邮件地址。大多数主要网站都不会给你太多信息; gmail的回复是“如果你试图邮寄它,我们会尝试发送它”或类似的东西。

答案 11 :(得分:1)

我认为你不能,有很多场景甚至发送电子邮件都会失败。例如。用户端的邮件服务器暂时关闭,邮箱存在但已满,因此无法传递邮件等。

这可能是在用户确认收到确认电子邮件后,很多网站验证注册的原因。

答案 12 :(得分:1)

我可以确认约瑟夫和德鲁的答案是否可以使用RCTP TO: <address_to_check>。我想在这些答案的上方添加一些小附录。

包罗万象的供应商

某些邮件提供商实施了包罗万象的策略,这意味着*@mydomain.com将对RCTP TO:命令返回肯定值。但这并不一定意味着邮箱“存在”,如“属于人类”。请注意,这里无能为力。

IP灰名单/黑名单

灰名单:来自未知IP的第一连接被阻止。解决方案:至少重试2次。

黑名单:如果您从同一IP发送太多请求,则该IP被阻止。解决方案:使用IP轮换; Reacher使用Tor。

注册表单上的HTTP请求

这是非常特定于提供程序的,但是您有时可以使用精心设计的HTTP请求,并解析这些请求的响应,以查看用户名是否已为此提供程序注册。

这是我编写的用于使用HTTP请求check-if-email-exists检查*@yahoo.com地址的开源库中的相关功能。我知道我的代码是Rust,该线程标记为PHP,但是同样的想法适用。

完整收件箱

这可能是一个极端情况,但是当用户的收件箱已满时,RCTP TO:将返回一条5.1.1 DSN错误消息,说明已满。这意味着该帐户实际存在!

披露

我运行Reacher,这是一个实时电子邮件验证API。我的代码是用Rust编写的,并且是100%开源的。如果需要更强大的解决方案,请检查一下:

Github:https://github.com/amaurymartiny/check-if-email-exists

结合各种技术,我设法验证了大约80%的电子邮件我的客户检查了。

答案 13 :(得分:-6)

<?php

   $email = "someone@exa mple.com";

   if(!filter_var($email, FILTER_VALIDATE_EMAIL))
      echo "E-mail is not valid";
   else
      echo "E-mail is valid";

?>