Как проверить, существует ли адрес электронной почты без отправки электронной почты? - PullRequest
109 голосов
/ 19 февраля 2009

Я наткнулся на этот код PHP, чтобы проверить адрес электронной почты с помощью SMTP без отправки электронного письма .

Кто-нибудь пробовал что-то подобное или у вас это работает? Можете ли вы сказать, правильно ли введен клиент / пользователь электронной почты?

Ответы [ 13 ]

84 голосов
/ 19 февраля 2009

Существует два метода, которые вы можете иногда использовать, чтобы определить, существует ли фактически получатель:

  1. Вы можете подключиться к серверу и выполнить команду VRFY. Очень немногие серверы поддерживают эту команду, но она предназначена именно для этого. Если сервер отвечает DSN 2.0.0, пользователь существует.

    Пользователь VRFY

  2. Вы можете выдать RCPT и проверить, отклонено ли письмо.

    ПОЧТА ОТ: <>

    RCPT TO:

Если пользователь не существует, вы получите DSN 5.1.1. Однако то, что электронное письмо не отклонено, не означает, что пользователь существует. Некоторые серверы будут молча отбрасывать подобные запросы, чтобы предотвратить перечисление своих пользователей. Другие серверы не могут подтвердить пользователя и должны принять сообщение независимо от того.

Существует также метод защиты от спама, называемый серым списком, который заставит сервер первоначально отклонить адрес, ожидая, что настоящий SMTP-сервер попытается повторно доставить его через некоторое время. Это приведет к путанице при попытке подтвердить адрес.

Честно говоря, если вы пытаетесь подтвердить адрес, лучше всего использовать простое регулярное выражение для блокировки явно недействительных адресов, а затем отправить фактическое электронное письмо со ссылкой обратно в вашу систему, чтобы проверить полученное электронное письмо. Это также гарантирует, что пользователь ввел свой фактический адрес электронной почты, а не небольшую опечатку, которая может принадлежать кому-то другому.

45 голосов
/ 18 декабря 2010

Другие ответы здесь обсуждают различные проблемы с попытками сделать это. Я подумал, что покажу, как вы можете попробовать это в случае, если вы хотите научиться, делая это самостоятельно.

Вы можете подключиться к почтовому серверу через 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 я считаю, что вы можете использовать fsockopen, fwrite и fread для программного выполнения вышеупомянутых шагов:

$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");
8 голосов
/ 19 февраля 2009

Общий ответ таков: вы можете , а не проверить, существует ли адрес электронной почты, если вы отправляете ему электронное письмо: он может просто попасть в черную дыру.

При этом описанный там метод довольно эффективен. Он используется в производственном коде в ZoneCheck за исключением того, что он использует RSET вместо QUIT.

Там, где взаимодействие пользователя с его почтовым ящиком не слишком дорого, многие сайты фактически проверяют, что почта куда-то приходит, отправляя секретный номер, который должен быть отправлен обратно отправителю (либо переходя на секретный URL-адрес, либо отправляя этот секретный номер по электронной почте ). Большинство списков рассылки работают так.

6 голосов
/ 20 мая 2011

Это не удастся (среди прочих случаев), когда целевой почтовый сервер использует серые списки.

Greylisting : SMTP-сервер отказывает в доставке при первом подключении ранее неизвестного клиента, разрешает в следующий раз; это позволяет избежать некоторого процента спам-ботов и разрешить законное использование - , так как ожидается, что законный отправитель почты попытается повторить , что и будут делать обычные агенты пересылки почты.

Однако, если ваш код проверяет только на сервере один раз , сервер с серыми списками будет отказывать в доставке (так как ваш клиент подключается в первый раз); если через некоторое время вы снова не зарегистрируетесь, возможно, вы ошибочно отклоняете действительные адреса электронной почты.

6 голосов
/ 19 февраля 2009

Не совсем ..... Некоторые серверы могут не проверять "rcpt to:"

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

Это создает угрозу безопасности .....

Если сервер это делает, вы можете написать бота для обнаружения каждого адреса на сервере ....

4 голосов
/ 19 февраля 2009

Некоторые проблемы:

  1. Я уверен, что некоторые SMTP-серверы немедленно сообщат вам, если адрес, который вы им дадите, не существует, но некоторые не будут использоваться в качестве меры конфиденциальности. Они просто примут любые адреса, которые вы им дадите, и молча проигнорируют несуществующие.
  2. Как говорится в статье, если вы будете делать это слишком часто на некоторых серверах, они попадут в черный список.
  3. Для некоторых SMTP-серверов (например, gmail) вам нужно использовать SSL для каких-либо действий. Это верно только при использовании SMTP-сервера gmail для отправки почты .
3 голосов
/ 11 февраля 2014
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
    }
}
2 голосов
/ 16 июня 2016

Хотя этот вопрос немного устарел, этот сервисный совет может помочь пользователям, ищущим подобное решение, проверять адреса электронной почты вне проверки синтаксиса перед отправкой.

Я использовал этот сервис с открытым исходным кодом для более глубокой проверки писем (проверка записей mx в домене адресов электронной почты и т. Д.) Для нескольких проектов с хорошими результатами. Он также проверяет на наличие общих опечаток, что довольно полезно. Демоверсия здесь .

2 голосов
/ 19 февраля 2009

Все, что вы можете сделать, это выполнить поиск DNS и убедиться, что в домене, указанном в адресе электронной почты, есть запись MX, за исключением того, что нет надежного способа справиться с этим.

Некоторые серверы могут работать с методом rcpt-to, когда вы общаетесь с SMTP-сервером, но это полностью зависит от конфигурации сервера. Другая проблема может быть в том, что перегруженный сервер может вернуть код 550, говорящий о том, что пользователь неизвестен, но это временная ошибка, существует постоянная ошибка (я думаю, 451?), Которую можно вернуть. Это зависит полностью от конфигурации сервера.

Я бы лично проверил запись MX в DNS, а затем отправил бы подтверждение по электронной почте, если запись MX существует.

2 голосов
/ 19 февраля 2009

«Можете ли вы сказать, правильно ли введен клиент / пользователь электронной почты?»

На самом деле это две разные вещи. Он может существовать , но может быть неверным.

Иногда вам нужно принять пользовательские данные по номиналу. В противном случае есть много способов победить систему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...