Come verificare se esiste un indirizzo e-mail senza inviare un'e-mail?


123

Mi sono imbattuto in questo codice PHP per controllare l'indirizzo e-mail utilizzando SMTP senza inviare un'e-mail .

Qualcuno ha provato qualcosa di simile o funziona per te? Puoi sapere se l'email inserita da un cliente / utente è corretta ed esiste?



2
Mi chiedo solo, perché questo ha il tag Telnet?
Piccolo

2
C'è una libreria PHP che fa esattamente questo: github.com/kickboxio/kickbox-php
Dan

Kickbox non è gratuito. Questa API è solo un wrapper per connettersi al loro servizio.
Ashit Vora

Risposte:


92

Esistono due metodi che a volte puoi utilizzare per determinare se un destinatario esiste effettivamente:

  1. Puoi connetterti al server ed emettere un VRFYcomando. Pochissimi server supportano questo comando, ma è inteso esattamente per questo. Se il server risponde con un DSN 2.0.0, l'utente esiste.

    VRFY user
  2. Puoi emettere un RCPTe vedere se la posta viene rifiutata.

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

Se l'utente non esiste, otterrai un DSN 5.1.1. Tuttavia, solo perché l'email non viene rifiutata, non significa che l'utente esista. Alcuni server ignoreranno silenziosamente richieste come questa per impedire l'enumerazione dei propri utenti. Altri server non possono verificare l'utente e devono accettare il messaggio a prescindere.

Esiste anche una tecnica antispam chiamata greylisting, che farà sì che il server inizialmente rifiuti l'indirizzo, aspettandosi che un vero server SMTP tenterà una riconsegna qualche tempo dopo. Questo rovinerà i tentativi di convalidare l'indirizzo.

Onestamente, se stai tentando di convalidare un indirizzo, l'approccio migliore è utilizzare una semplice regex per bloccare indirizzi ovviamente non validi, quindi inviare un'e-mail effettiva con un collegamento al tuo sistema che convaliderà l'e-mail ricevuta. Ciò garantisce anche che l'utente abbia inserito la propria email effettiva, non un leggero errore di battitura che appartiene a qualcun altro.


10
Alcuni server accetteranno anche il messaggio, ma successivamente invieranno un messaggio di errore al mittente della busta, soprattutto se si tratta di una grande organizzazione con molti reparti interni con i propri server di posta. Il server di frontiera potrebbe anche non conoscere tutti gli account all'interno.
David Mårtensson,

3
Allora perché gli spammer non usano questo metodo per verificare i dipendenti dalla posta elettronica? Voglio dire a parte il fatto che questi metodi sono supportati da pochissimi server. Oppure lo fanno?
Shahriyar Imanov

7
@ Shehi: In realtà gli spammer possono utilizzare questo metodo, è difficile da dire. Tuttavia, poiché gli spammer potrebbero usarlo, quasi tutti i server di posta disabilitano VRFY, quindi in pratica VRFY è probabilmente inutile.
sleske

2
Potete fornire un esempio di codice su come utilizzare un RCPT A: <utente @ dominio>? Grazie
Papa De Beau

4
A VRFY, gmail risponde "Invia qualche mail, farò del mio meglio" ;-)
Armel Larcier

46

Altre risposte qui illustrano i vari problemi con il tentativo di eseguire questa operazione. Ho pensato di mostrarti come potresti provare questo nel caso in cui volessi imparare facendolo da solo.

È possibile connettersi a un server di posta tramite telnet per chiedere se esiste un indirizzo di posta elettronica. Ecco un esempio di test di un indirizzo e-mail per stackoverflow.com:

C: \> nslookup -q = mx stackoverflow.com
Risposta non autorevole:
preferenza MX stackoverflow.com = 40, Mail Exchanger = STACKOVERFLOW.COM.S9B2.PSMTP.com
preferenza MX stackoverflow.com = 10, Mail Exchanger = STACKOVERFLOW.COM.S9A1.PSMTP.com
preferenza MX stackoverflow.com = 20, Mail Exchanger = STACKOVERFLOW.COM.S9A2.PSMTP.com
preferenza MX stackoverflow.com = 30, Mail Exchanger = STACKOVERFLOW.COM.S9B1.PSMTP.com

C: \> telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 pronto. La sezione 17538.45 del codice CA Business and Professions vieta l'uso di questo sistema per annunci di posta elettronica non richiesti.

helo hi
250 Postini saluta di nuovo

posta da: <me@myhost.com>
250 Ok

rcpt a: <fake@stackoverflow.com>
550-5.1.1 L'account di posta elettronica a cui si è tentato di accedere non esiste. Vi preghiamo di provare
550-5.1.1 ricontrollare l'indirizzo e-mail del destinatario per errori di battitura o
550-5.1.1 spazi non necessari. Ulteriori informazioni su
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 w41si3198459wfd.71

Le righe precedute da codici numerici sono risposte dal server SMTP. Ho aggiunto alcune righe vuote per renderlo più leggibile.

Molti server di posta non restituiranno queste informazioni come mezzo per impedire la raccolta di indirizzi e-mail da parte degli spammer, quindi non puoi fare affidamento su questa tecnica. Tuttavia potresti avere qualche successo nel ripulire alcuni indirizzi e-mail ovviamente cattivi rilevando server di posta non validi o facendo rifiutare gli indirizzi dei destinatari come sopra.

Nota anche che i server di posta potrebbero inserirti nella lista nera se ne fai troppe richieste.


In PHP Credo che si può usare fsockopen, fwritee freadper eseguire i passaggi sopra a livello di codice:

$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");

giù i cappelli! un problema che ho trovato è che la porta 25 funziona sempre con record mx a bassa priorità?
Dhruvenkumar Shah

@DhruvenkumarShah, mi dispiace non lo so. Se lo scopri, commenta di nuovo.
Drew Noakes

Ciao, stavo solo cercando il mio account universitario per scoprire tutto sui record MX, ma non ha funzionato per 25 .. ma il tipo di sito web di verifica-email.org online ha funzionato .. come lo stanno facendo .. Io ti farò sapere se lo scopro
Dhruvenkumar Shah

1
@DhruvenkumarShah fornisce pochi nomi di server di scambio di posta. vedi la risposta per gli scambiatori di posta. quindi se uno fallisce, l'altro dalla lista dovrebbe funzionare.
Janaka R Rajapaksha

davvero di grande aiuto per me .. grazie signore..ho provato con lo stucco e funziona come un incantesimo .. grazie ..
Mohammed Sufian

8

La risposta generale è che si può non verificare se un indirizzo email esiste evento se si invia una e-mail ad esso: si potrebbe basta andare in un buco nero.

Detto questo, il metodo qui descritto è abbastanza efficace. Viene utilizzato nel codice di produzione in ZoneCheck tranne per il fatto che utilizza RSET invece di QUIT.

Dove l'interazione dell'utente con la sua casella di posta non è eccessivamente costosa, molti siti testano effettivamente che la posta arrivi da qualche parte inviando un numero segreto che deve essere rispedito all'emittente (o andando a un URL segreto o inviando questo numero segreto via e-mail). La maggior parte delle mailing list funziona così.



6

Questo fallirà (tra gli altri casi) quando il mailserver di destinazione usa il greylisting.

Greylisting : il server SMTP rifiuta la consegna la prima volta che un client precedentemente sconosciuto si connette, consente la prossima volta; questo tiene fuori una certa percentuale di spam, pur consentendo un uso legittimo, poiché ci si aspetta che un mittente di posta legittimo riproverà , che è ciò che faranno i normali agenti di trasferimento della posta.

Tuttavia, se il codice controlla sul server solo una volta , un server con greylisting negherà la consegna (poiché il client si connette per la prima volta); a meno che non controlli di nuovo tra poco, potresti rifiutare erroneamente indirizzi e-mail validi.


(esperienza personale: ho dovuto discutere avanti e indietro con il mio provider di posta elettronica che , sono consapevole di quello che sto facendo e , ho bisogno del greylisting disattivato - perché questi controlli da un servizio di terze parti stavano fallendo )
Piskvor ha lasciato l'edificio

4

Qualche problema:

  1. Sono sicuro che alcuni server SMTP ti faranno sapere immediatamente se un indirizzo che fornisci loro non esiste, ma alcuni non lo faranno come misura di privacy. Accetteranno semplicemente qualsiasi indirizzo tu dia loro e ignoreranno silenziosamente quelli che non esistono.
  2. Come dice l'articolo, se lo fai troppo spesso con alcuni server, ti inseriranno nella lista nera.
  3. Per alcuni server SMTP (come gmail), è necessario utilizzare SSL per fare qualsiasi cosa. Questo è vero solo quando si utilizza il server SMTP di Gmail per inviare e-mail.

Per quanto riguarda il terzo punto, questo accade solo se vuoi usarlo come staffetta. Non conosco nessuno scambiatore di posta che richieda SSL. Se qualcuno lo facesse, smetterebbe di ricevere email da molti utenti.
kmkaplan

Scusa, errore mio. Se desideri inviare e-mail utilizzando il server SMTP di Gmail, devi utilizzare SSL.
Graeme Perrow,

3

Sebbene questa domanda sia un po 'vecchia, questo suggerimento di servizio potrebbe aiutare gli utenti alla ricerca di una soluzione simile controllando gli indirizzi e-mail oltre la convalida della sintassi prima dell'invio.

Ho utilizzato questo servizio open source per una convalida più approfondita delle e-mail (controllo dei record mx nel dominio dell'indirizzo e-mail, ecc.) Per alcuni progetti con buoni risultati. Controlla anche errori di battitura comuni, la strega è abbastanza utile. Demo qui .


Sostieni che questo servizio sia open source. Potresti fornire un collegamento alla fonte?
amaurymartiny

Mi dispiace @amaurymartiny non posso. Al momento della stesura di questo articolo, il progetto Mailgun era open source, se ricordo bene, ma non sono riuscito a trovare un collegamento a qualsiasi repo che fornisse la fonte dopo questa volta.
Henkealg

2

"Puoi dire se l'email inserita da un cliente / utente è corretta ed esiste?"

In realtà queste sono due cose separate. Potrebbe esistere ma potrebbe non essere corretto.

A volte devi prendere gli input dell'utente al valore nominale. Ci sono molti modi per sconfiggere il sistema altrimenti.


2
+1 Non puoi mai essere sicuro che sia corretto senza inviare un'e-mail e ottenere effettivamente una risposta umana, ad esempio facendo clic su un collegamento.
Daniel Daranas

puoi mantenere un collegamento (per un'immagine, ecc.) nel corpo dell'email e contare ogni carico per quel collegamento. non c'è bisogno di aspettare i clic
Janaka R Rajapaksha

2

Tutto quello che puoi fare è cercare DNS e assicurarti che il dominio che si trova nell'indirizzo e-mail abbia un record MX, a parte questo non esiste un modo affidabile per gestirlo.

Alcuni server possono funzionare con il metodo rcpt-to in cui parli al server SMTP, ma dipende interamente dalla configurazione del server. Un altro problema potrebbe essere che un server sovraccarico può restituire un codice 550 che dice che l'utente è sconosciuto, ma questo è un errore temporaneo, c'è un errore permanente (451 penso?) Che può essere restituito. Dipende interamente dalla configurazione del server.

Personalmente controllerei il record MX DNS, quindi invierei una verifica tramite e-mail se il record MX esiste.


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
la porta 80 non ha senso
jrosell il

5
Penso che stia solo controllando l'esistenza del nome di dominio piuttosto che controllare l'email stessa.
The Angry Saxon

Questo potrebbe essere più utile:getmxrr
jchook

1

Supponendo che sia l' indirizzo dell'utente , alcuni server di posta consentono al comando SMTP VRFY di verificare effettivamente l'indirizzo di posta elettronica rispetto alle sue cassette postali. La maggior parte del sito principale non ti darà molte informazioni; la risposta di Gmail è "se provi a inviarlo per posta, proveremo a consegnarlo" o qualcosa di così intelligente.


1

Penso che non puoi, ci sono così tanti scenari in cui anche l'invio di un'e-mail può fallire. Per esempio. il server di posta sul lato utente è temporaneamente inattivo, la casella di posta esiste ma è piena, quindi il messaggio non può essere recapitato, ecc.

Questo è probabilmente il motivo per cui così tanti siti convalidano una registrazione dopo che l'utente ha confermato di aver ricevuto l'e-mail di conferma.


0

Posso confermare le risposte di Joseph e Drew da utilizzare RCTP TO: <address_to_check> . Vorrei aggiungere alcune piccole aggiunte oltre a queste risposte.

Provider catch-all

Alcuni provider di posta implementano un criterio catch-all, il che significa che *@mydomain.comtornerà positivo al fileRCTP TO: comando. Ma questo non significa necessariamente che la casella di posta "esista", come in "appartiene a un essere umano". Non si può fare molto qui, basta essere consapevoli.

Greylisting IP / Blacklisting

Greylisting: la prima connessione da IP sconosciuto è bloccata. Soluzione: riprova almeno 2 volte.

Blacklisting: se invii troppe richieste dallo stesso IP, questo IP viene bloccato. Soluzione: utilizzare la rotazione IP; Reacher utilizza Tor.

Richieste HTTP sui moduli di iscrizione

Questo è molto specifico del provider, ma a volte è possibile utilizzare richieste HTTP ben congegnate e analizzare le risposte di queste richieste per vedere se un nome utente è già registrato o meno con questo provider.

Ecco la funzione rilevante da una libreria open source che ho scritto per controllare gli *@yahoo.comindirizzi utilizzando le richieste HTTP: check-if-email-exist . So che il mio codice è Rust e questo thread è contrassegnato con PHP, ma valgono le stesse idee.

Posta in arrivo piena

Questo potrebbe essere un caso limite, ma quando l'utente ha una casella di posta piena, RCTP TO:restituirà un 5.1.1 DSNmessaggio di errore che dice che è pieno. Ciò significa che l'account esiste davvero!

Divulgazione

Corro Reacher , un tempo reale verifica email API. Il mio codice è scritto in Rust ed è open source al 100%. Dai un'occhiata se desideri una soluzione più robusta:

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

Con una combinazione di varie tecniche per saltare i cerchi, riesco a verificare circa l'80% delle e-mail controllate dai miei clienti.


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

?>

L'utente chiede una soluzione .Net non php.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.