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

我偶然发现了这个 PHP 代码使用 SMTP 检查电子邮件地址而不发送电子邮件

有没有人试过类似的方法,或者对你有效?你能告诉一个电子邮件客户/用户输入是正确的和存在的吗?

251798 次浏览

并非如此... ... 某些服务器可能不检查“ rcpt to:”

Http://www.freesoft.org/cie/rfc/1123/92.htm

这样做是有安全风险的... ..。

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

一般的答案是,你可以 没有检查是否有一个电子邮件地址存在的事件,如果你发送一封电子邮件给它: 它可能只是进入黑洞。

尽管如此,这里描述的方法是相当有效的。除了使用 RSET 而不是 QUIT 之外,它在 ZoneCheck的生产代码中使用。

如果用户与邮箱的交互不会过于昂贵,许多网站实际上会通过发送一个必须发送回发射器的秘密号码来测试邮件是否到达了某个地方(或者通过访问一个秘密 URL,或者通过电子邮件发送回这个秘密号码)。大多数邮件列表都是这样工作的。

一些问题:

  1. 我相信,如果您提供的地址不存在,一些 SMTP 服务器会立即通知您,但是作为一种隐私措施,有些服务器则不会。他们只会接受你给他们的任何地址然后默默地忽略那些不存在的地址。
  2. 正如本文所述,如果您在某些服务器上过于频繁地这样做,他们将把您列入黑名单。
  3. 对于某些 SMTP 服务器(如 gmail) ,您需要使用 SSL 来完成任何操作。只有在使用 gmail 的 SMTP 服务器发送 发送邮件时才会出现这种情况。

“你能告诉电子邮件客户/用户输入是否正确和存在?”

实际上这是两件不同的事情。它可能是 存在,但可能不正确。

有时候,您必须以用户输入的面值为依据。否则有很多方法可以击败这个系统。

假设它是 使用者的地址,一些邮件服务器确实允许 SMTP VRFY 命令根据其邮箱实际验证电子邮件地址。大多数主流网站不会给你太多信息; gmail 的回复是“如果你尝试邮寄,我们会尝试发送”或者类似这样的巧妙的回复。

我认为你不能,有太多的情况下,即使发送一封电子邮件也可能失败。例如,用户端的邮件服务器暂时关闭,邮箱已满,因此无法发送邮件等。

这可能就是为什么这么多网站在用户确认他们已经收到确认电子邮件后验证注册的原因。

关于所有你可以做的是搜索 DNS,并确保在电子邮件地址的域有一个 MX 记录,除了没有可靠的方法来处理这一点。

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

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

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

  1. 您可以连接到服务器,并发出 VRFY命令。很少有服务器支持这个命令,但它正是为此而设计的。如果服务器使用2.0.0 DSN 进行响应,则存在该用户。

    VRFY user
    
  2. You can issue a RCPT, and see if the mail is rejected.

    MAIL FROM:<>
    RCPT TO:<user@domain>
    

If the user doesn't exist, you'll get a 5.1.1 DSN. However, just because the email is not rejected, does not mean the user exists. Some server will silently discard requests like this to prevent enumeration of their users. Other servers cannot verify the user and have to accept the message regardless.

There is also an antispam technique called greylisting, which will cause the server to reject the address initially, expecting a real SMTP server would attempt a re-delivery some time later. This will mess up attempts to validate the address.

Honestly, if you're attempting to validate an address the best approach is to use a simple regex to block obviously invalid addresses, and then send an actual email with a link back to your system that will validate the email was received. This also ensures that they user entered their actual email, not a slight typo that happens to belong to somebody else.

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

您可以通过 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");

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

Greylist : SMTP 服务器在以前未知的客户端第一次连接时拒绝交付,允许下一次连接; 这保留了一定比例的垃圾邮件机器人,同时允许合法使用 -因为预计合法的邮件发送者将重试,这是正常的邮件传输代理将做的事情。

但是,如果您的代码只检查服务器 一次,那么带有灰名单的服务器将拒绝传递(因为您的客户机是第一次连接) ; 除非您稍后再次检查,否则您可能会错误地拒绝有效的电子邮件地址。

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
}
}
<?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";


?>

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

我一直在使用这个 开源服务对一些项目的电子邮件进行更深入的验证(检查电子邮件地址域上的 mx 记录等) ,结果很好。它还检查常见的拼写错误,非常有用。演示 给你

我可以用 RCPT TO: <address_to_check>来确认约瑟夫和德鲁的答案。我想在这些答案之上添加一些小补充。

全方位供应商

一些邮件提供程序实现了一个“全部捕获”策略,这意味着 *@mydomain.com将返回正值给 RCPT TO:命令。但这并不一定意味着邮箱“存在”,就像“属于一个人”那样。在这里什么也做不了,只是要注意。

IP 灰名单/黑名单

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

黑名单: 如果你从同一个 IP 发送太多请求,这个 IP 被阻塞。解决方案: 使用 IP 旋转。

在注册表单上的 HTTP 请求

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

下面是我为了使用 HTTP 请求检查 *@yahoo.com地址而编写的一个开源库的相关函数: 检查电子邮件是否存在。我知道我的代码是 Rust,这个线程是标记为 PHP 的,但是同样的想法也适用。

完整收件箱

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

披露

我运行[ Reacher ][1] ,一个实时电子邮件验证 API。我的代码是用 Rust 编写的,而且是100% 开源的。如果你想要一个更健壮的解决方案,可以试试这个:

https://github.com/reacherhq/check-if-email-exists

通过各种技术的组合跳过环,我设法验证 大约80% 的电子邮件我的客户检查。

你有很多简单的在线工具,比如 https://mail7.net

此服务检查电子邮件地址格式,然后确保域名是有效的,并提取 MX 记录。 所以在90% 的情况下,你可以确定它是否有效。90% ,因为一些邮件服务器没有参与该过程。