A legjobb módszer email címek validálására

RoliSoft
2010 May 31, Monday 19:00

Email címet validálni egy nagyon nehéz feladat. Ha azt hiszed, hogy egy szimpla [a-z0-9]+@[a-z0-9]+\.[a-z]+ reguláris kifejezés megteszi, akkor nagyon rossz hírem van neked. &*=?^+{}'~@árvíztűrő-tükörfúrógép.net bizony egy szintaktikailag valid email cím.

Ha meg szeretnéd tudni egész pontosan hogyan is kell validálni egy címet, akkor a következőket tanulmányozd:

  1. RFC0822 – Az eredeti specifikáció; az egyetlen problémája, hogy 1982-ben lett megírva, úgyhogy...
  2. RFC1123, 5.2.15 RFC-822 Syntax Change
  3. RFC2822, 3.4. Address Specification

Ha sikerült keresni vagy összedobni egy reguláris kifejezést, ami ezeknek a feltételeknek megfelelően validál, akkor jön a következő kérdés: a cím valid, de létezik-e az a cím? És igen, ezt könnyen le lehet ellenőrözni.

Ebben a cikkben bemutatom, hogy hogyan lehet egy email címet teljesen leellenőrizni három lépésből.

Első lépés – Az email cím szintaktikai ellenőrzése

Noha nem létezik olyan reguláris kifejezés ami tökéletesen validálna, léteznek olyanok amik közel vannak hozzá.

Ha egy egyszerű preg_match-et szeretnél használni egy cím validálásához, akkor a következő reguláris kifejezés a legjobb (a cikk írásakor):

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i

Ha pedig inkább egy pontosabb függvényt szeretnél használni akkor meg töltsd le az EmailAddressValidation osztályt. A használata nagyon egyszerű:

include('EmailAddressValidator.php');

$validator = new EmailAddressValidator;

if ($validator->check_email_address('rolisoft@gmail.com')) { 
    // A cím szintaktikailag helyes, jöhet a következő lépés...
} else {
    die('A beírt email cím nem helyes!');
}

Második lépés – Tud-e a domain emaileket fogadni

Megnézzük hogy az email cím domainjének van-e MX vagy A rekordjai. Ha nincs, akkor nem tud emailt fogadni.

rolisoft@ncc1701e:~$ nslookup -type=MX gmail.com
Server:         208.113.192.18
Address:        208.113.192.18#53

Non-authoritative answer:
gmail.com       mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.

rolisoft@ncc1701e:~$ nslookup -type=A gmail.com
Server:         208.113.192.18
Address:        208.113.192.18#53

Non-authoritative answer:
Name:   gmail.com
Address: 209.85.225.83
Name:   gmail.com
Address: 74.125.79.83
Name:   gmail.com
Address: 74.125.127.83

PHP-ből az MX és A rekordokat a Net_DNS segítségével lehet megnézni.

Harmadik lépés – Megpróbálunk emailt küldeni

Megpróbálunk csatlakozni az előzőleg kapott MX vagy A rekordokhoz és megpróbálunk elküldeni egy emailt. A cím beírása után a mail server figyelmeztet ha a cím nem létezik, ha pedig létezik akkor kijelentkezünk.

Egy létező email cím esetén így folyik le a beszélgetés:

rolisoft@ncc1701e:~$ telnet gmail-smtp-in.l.google.com 25
Trying 209.85.212.84...
Connected to mail-vw0-f84.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP 16si12020910vwj.23
HELO rolisoft.net
250 mx.google.com at your service
MAIL FROM: <address-probe@rolisoft.net>
250 2.1.0 OK 16si12020910vwj.23
RCPT TO: <rolisoft@gmail.com>
250 2.1.5 OK 16si12020910vwj.23
QUIT
221 2.0.0 closing connection 16si12020910vwj.23
Connection closed by foreign host.

Ha pedig nem létezik az email cím, akkor:

rolisoft@ncc1701e:~$ telnet gmail-smtp-in.l.google.com 25
Trying 209.85.210.8...
Connected to mail-yx0-f8.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP 8si21418269yxe.0
HELO rolisoft.net
250 mx.google.com at your service
MAIL FROM: <address-probe@rolisoft.net>
250 2.1.0 OK 8si21418269yxe.0
RCPT TO: <nem-regisztralt-cim@gmail.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 8si21418269yxe.0
QUIT
221 2.0.0 closing connection 8si21418269yxe.0
Connection closed by foreign host.

Ezek után teljesen biztos lehetsz, hogy egy email cím létezik, és nem kelletett megerősítő emailt sem küldened a felhasználónak. Meg kell említenem ugyan, hogy ez a módszer sem véd a disposable email szolgáltatások – mint például mailinator.com – ellen, ugyanis ott bármilyen cím el lesz fogadva.

Bemutatóként megvalósítottam PHP-ben a fenti három lépést. Az ékezetes domainek egyelőre nem mennek át a második lépésen, ugyanis a Net_DNS meg a PHP úgy nagyjából eléggé shit és nem támogatja még az ékezetes domaineket.

Próbáld ki:

Hozzászólások
Javitanek a fenti regularis kifejezesen. Feltunoen sok benne a felesleges escape-eles.

Ha minden igaz, a kovetkezo is ugyanazt teszi.

/^([-\w!#$%&'*+/=?^`{|}~]+\.)*[-\w!#$%&'*+/=?^`{|}~]+@((((([a-z0-9]{1}[a-z0-9-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
ezzel csak az az egy baj van, hogy - ha jól tudom - az én domain-regisztrátorom névszerverei a spammerek miatt minden címre 250 acceptedet adnak vissza, hogy ezzel a módszerrel ne lehessen kideríteni a létező címeket. ha jól tudom.
Egyébként a google is olyan mint a mailinator, csak ott tényleg létezik :-)
Naja az email cím valid, de nem biztos hogy azé aki megadta... sztem az aktiváló email küldést nem lehet megúszni...

---
atxatx
http://ingyenjatekok.dynanix.com