Как проверить, существует ли адрес электронной почты, не отправляя электронное письмо?

123

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

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

PHP-парень
источник
2
Просто интересно, почему у этого есть тег Telnet?
Piccolo
2
Есть библиотека PHP, которая делает именно это: github.com/kickboxio/kickbox-php
Дэн
Kickbox не является бесплатным. Этот API - просто оболочка для подключения к их сервису.
Ашит Вора,

Ответы:

92

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

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

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

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

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

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

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

Джозеф Тэри
источник
10
Некоторые серверы даже примут сообщение, но позже отправят сообщение об ошибке обратно отправителю конверта, особенно если это большая организация с множеством внутренних отделов со своими собственными почтовыми серверами. Пограничный сервер может даже не знать все учетные записи внутри.
Дэвид Мортенссон
3
Тогда почему спамеры не используют этот метод для проверки почтовых пользователей? Я имею в виду тот факт, что эти методы поддерживаются очень немногими серверами. Или они?
Шахрияр Иманов
7
@Shehi: На самом деле спамеры могут использовать этот метод, это сложно сказать. Однако, поскольку его могут использовать спамеры , почти все почтовые серверы отключают VRFY, поэтому на практике VRFY, вероятно, бесполезен.
sleske
2
Не могли бы вы привести пример кода, как использовать RCPT TO: <user @ domain>? Спасибо
Папа Де Бо
4
На VRFY gmail отвечает: «Отправьте письмо, я постараюсь изо всех
сил
46

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

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

C: \> nslookup -q = mx stackoverflow.com
Неавторитетный ответ:
stackoverflow.com MX предпочтение = 40, почтовый обменник = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackoverflow.com MX предпочтение = 10, почтовый обменник = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackoverflow.com MX предпочтение = 20, почтовый обменник = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackoverflow.com MX предпочтение = 30, почтовый обменник = STACKOVERFLOW.COM.S9B1.PSMTP.com

C: \> telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 готов. Раздел 17538.45 Кодекса бизнеса и профессий CA запрещает использование этой системы для нежелательной рекламы по электронной почте.

привет привет
250 Postini передает привет

почта от: <me@myhost.com>
250 ок

rcpt на: <fake@stackoverflow.com>
550-5.1.1 Учетная запись электронной почты, к которой вы пытались подключиться, не существует. Пожалуйста попробуйте
550-5.1.1 двойная проверка адреса электронной почты получателя на предмет опечаток или
550-5.1.1 лишние пробелы. Узнайте больше на
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");
Дрю Ноукс
источник
сними шляпу! я обнаружил одну проблему: всегда ли порт 25 работает с записью mx низкого приоритета ??
Дхрувенкумар Шах
@DhruvenkumarShah, извини, я не знаю. Если вы узнаете, прокомментируйте еще раз.
Дрю Ноукс
Привет, я просто пытался для своей учетной записи в университете узнать все о записях MX, но это не сработало для 25 .. но веб-сайт типа online verify-email.org действительно работал .. как они это делают .. Я
сообщу
1
@DhruvenkumarShah дает несколько имен почтовых серверов. см. ответ для почтовых обменников. поэтому, если один из них не работает, другой из списка должен работать.
Джанака Р. Раджапакша
действительно очень помогло мне ... спасибо, сэр ... я попробовал это в замазке и работает как шарм ... спасибо ..
Мохаммед Суфиан
8

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

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

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

kmkaplan
источник
6

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

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

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

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

l_39217_l
источник
Я тоже думал об этом :)
Джанака Р. Раджапакша
6

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

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

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

Писквор вышел из здания
источник
(личный опыт: мне приходилось спорить со своим провайдером электронной почты, что да , я знаю, что делаю, и да , мне нужно выключить серый список - потому что эти проверки сторонней службы не давали )
Писквор выехал из здания
4

Некоторые вопросы:

  1. Я уверен, что некоторые SMTP-серверы немедленно сообщат вам, если адрес, который вы им предоставили, не существует, но некоторые не будут в качестве меры конфиденциальности. Они просто примут любые адреса, которые вы им дадите, и молча игнорируют те, которых не существует.
  2. Как говорится в статье, если вы делаете это слишком часто с некоторыми серверами, они занесут вас в черный список.
  3. Для некоторых SMTP-серверов (например, Gmail) вам нужно использовать SSL, чтобы что-то делать. Это верно только при использовании SMTP-сервера Gmail для отправки электронной почты.
Грэм Перроу
источник
Что касается третьего пункта, это происходит только в том случае, если вы хотите использовать его в качестве реле. Я не знаю ни одного почтового обменника, который требует SSL. Если бы кто-то сделал это, они бы перестали получать электронную почту от многих пользователей.
kmkaplan
Извините моя ошибка. Если вы хотите отправлять электронную почту с помощью SMTP-сервера Gmail, вы должны использовать SSL.
Грэм Перроу,
3

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

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

Henkealg
источник
Вы утверждаете, что эта услуга имеет открытый исходный код. Не могли бы вы дать ссылку на источник?
amaurymartiny
Извините, @amaurymartiny, я не могу. На момент написания проекта Mailgun был открытым исходным кодом, если я правильно помню, но я не могу найти ссылку на какое-либо репо, предоставляющее исходный код после этого времени.
Henkealg,
2

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

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

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

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

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

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

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

Брайан Ребейн
источник
2
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
    }
}
Сэчин
источник
1
порт 80 не имеет смысла
Джроселл
5
Я думаю, что это просто проверка существования доменного имени, а не проверка самой электронной почты.
Angry Saxon
Это может быть более полезно:getmxrr
jchook
1

Предполагая, что это адрес пользователя , некоторые почтовые серверы позволяют команде SMTP VRFY фактически проверять адрес электронной почты по своим почтовым ящикам. Большая часть крупного сайта не предоставит вам много информации; ответ Gmail - «если вы попытаетесь отправить его по почте, мы постараемся доставить его» или что-то в этом роде.

Остин Салонен
источник
1

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

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

PhiLho
источник
0

Я могу подтвердить ответы Джозефа и Дрю, чтобы использовать RCTP TO: <address_to_check>. Я хотел бы добавить несколько небольших дополнений к этим ответам.

Все поставщики

Некоторые почтовые провайдеры реализуют универсальную политику, что означает, что команда *@mydomain.comвернет положительный результат RCTP TO:. Но это не обязательно означает, что почтовый ящик «существует», как в «принадлежит человеку». Здесь ничего особенного сделать нельзя, просто имейте в виду.

Серый / черный список IP-адресов

Серый список: 1-е соединение с неизвестного IP заблокировано. Решение: повторите попытку как минимум 2 раза.

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

HTTP-запросы в формах регистрации

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

Вот соответствующая функция из библиотеки с открытым исходным кодом, которую я написал для проверки *@yahoo.comадресов с помощью HTTP-запросов: check-if-email-exists . Я знаю, что мой код - Rust, и эта ветка помечена как PHP, но применимы те же идеи.

Полный почтовый ящик

Это может быть крайний случай, но когда у пользователя полный почтовый ящик, RCTP TO:он вернет 5.1.1 DSNсообщение об ошибке, в котором говорится, что он заполнен. Это означает, что учетная запись действительно существует!

раскрытие

Я использую Reacher , API проверки электронной почты в реальном времени. Мой код написан на Rust и полностью открыт. Проверьте это, если вам нужно более надежное решение:

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

С помощью комбинации различных техник, позволяющих преодолеть препятствия, мне удается проверить около 80% писем, которые проверяют мои клиенты.

amaurymartiny
источник
-8
<?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";

?>
user4314333
источник
Пользователь запрашивает решение .Net, а не php.