Как стать автором
Обновить

Валидация Email

Здравствуй %habrauser%.


Буквально вчера на Хабрахабре был опубликован перевод «Прекратите проверять Email с помощью регулярных выражений!», правильно. Прекратите. Есть способ проверки существования email куда более эффективный.


Если интересно – прошу под кат.



Для начала я попробую объяснить принцип идеи, а она очень проста. Получаем MX запись для домена и пробуем провести диалог с сервером. Просто? Проверим.
Проверку я делал на сервере gmail.


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


user@server:~# dig MX gmail.com

; <<>> DiG 9.7.3 <<>> MX gmail.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38407
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;gmail.com.                     IN      MX

;; ANSWER SECTION:
gmail.com. 3600    IN      MX      10 alt1.gmail-smtp-in.l.google.com.
gmail.com. 3600    IN      MX      30 alt3.gmail-smtp-in.l.google.com.
gmail.com. 3600    IN      MX      40 alt4.gmail-smtp-in.l.google.com.
gmail.com. 3600    IN      MX      20 alt2.gmail-smtp-in.l.google.com.
gmail.com. 3600    IN      MX      5  gmail-smtp-in.l.google.com.

;; Query time: 18 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Apr  4 20:24:58 2013
;; MSG SIZE  rcvd: 150

Как видим записей много, целых пять штук. Но ничего страшного.


user@server:~# telnet alt1.gmail-smtp-in.l.google.com. 25
Connected to mx.example.com.
220 mx.google.com ESMTP fz8127fd6407obb.42 - gsmtp

Берём первую запись и нам везёт – сервер откликается, соединение установлено.


Не ждём долго, приветствуем и представляемся.


HELO example.com
250 mx.google.com at your service
MAIL FROM: <noreply@example.com>
250 2.1.0 OK fz8127fd6407obb.42 – gsmtp

Замечательно, нас рады видеть и ждут не дождутся, когда мы назовём адресата. Адресата? Да, пожалуйста!


RCPT TO: <abuse@gmail.com>
250 2.1.5 OK fz8127fd6407obb.42 – gsmtp

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


QUIT
221 2.0.0 closing connection fz8127fd6407obb.42 – gsmtp
Connection closed by foreign host.
user@server:~#

Если адресат не существует, сервер должен вернуть код #550 или #553, если адресат не однозначен. У гугла это выглядит примерно так:


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://support.google.com/mail/bin/answer.py?answer=6596 fz8127fd6407obb.42 – gsmtp

На этом, как не странно – всё. Вот такая достаточно простая процедура позволяет нам узнать о том, не обманул ли нас и не ошибся ли наш драгоценный пользователь.


Пример на php на github.


Подробно про протокол можно почитать тут RFC 5321.


Надеюсь, что этот топик показался Вам полезным. И спасибо Вам, что дочитали до конца.


P.S. Я лично этот способ на продакшене не проверял. И подтвердить его работоспособность, с большим потоком проверок, не могу. Но в теории должно работать без проблем.


P.S.S. Да, может случится так, что пользователь введёт корректный email, но его почтовый сервер в этот момент будет недоступен. Это, действительно, возможный и не очень приятный вариант развития событий. Но и классическое письмо с кодом подтверждения будет валяться в очереди на отправку… если вообще отправится.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.