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

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

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

16 ответов

Решение

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

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

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

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

    ПОЧТА ОТ:<>

    RCPT TO:

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

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

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

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

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

C: \> nslookup -q = mx stackru.com Неавторизованный ответ:
stackru.com предпочтение MX = 40, почтовый обменник = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackru.com предпочтение MX = 10, почтовый обменник = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackru.com предпочтение MX = 20, почтовый обменник = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackru.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 передал привет назад по электронной почте: 250 Ok rcpt to: 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@stackru.com>\r\n");

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

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

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

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

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

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

Я могу подтвердить ответы Джозефа и Дрю, чтобы использовать 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% писем, которые проверяют мои клиенты.

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

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

Это риск для безопасности.....

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

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

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

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

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

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

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

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

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

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
    }
}

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

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

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

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

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

У вас есть много простых онлайн-инструментов, таких как https://mail7.net.

Эта служба проверяет формат адреса электронной почты, затем проверяет правильность доменного имени и извлекает записи MX. Так что в 90% вы можете быть уверены, что это действительно так. 90% потому что некоторые почтовые серверы не участвуют в процессе.

Я немного опоздал, но это может кому-то помочь.

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

          if(isEmialExist("EMAIL_ADDRESS_THAT"))
{
    echo "email exists, real email";
}
else
{
    echo "email doesn't exist";
}


function isEmialExist($emailAddress)
{
    if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) {
     return false; //invalid format
    }
    //now check if email really exist
    $postdata = http_build_query(array('api_key' => 'YOUR_API_KEY', 'email' => $emailAddress ));
    $url = "https://email-validator.com/api/v1.0/json";
    $opts = array('http' => array( 'method'  => 'POST', 'header'  => 'Content-Type: application/x-www-form-urlencoded', 'content' => $postdata ));
    
    $context  = stream_context_create($opts);
    $result = file_get_contents($url, false, $context);
    $data = json_decode($result, false);
    return $data->is_exists;
}

Более подробную информацию вы можете найти здесь. https://email-validator.com/tutorial

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

?>
Другие вопросы по тегам