Email 是最經常使用的用戶識別手段。php
開發者經常須要驗證郵箱的真實性。通常的方法是,註冊時向該郵箱發出一封驗證郵件,要求用戶點擊郵件裏面的連接。html
可是不少時候(好比要搞郵件營銷時),拿到的是成千上萬現成的 Email 地址,不可能經過回覆確認真實性,這時該怎麼辦呢?web
答案就是使用 SMTP 協議。本文將介紹如何經過該協議驗證郵箱的真假。bash
另外,結尾處還有一則移動端 H5 開發的培訓消息,歡迎關注。服務器
SMTP 是"簡單郵件傳輸協議"(Simple Mail Transfer Protocol)的縮寫,基於 TCP 協議,用來發送電子郵件。tcp
只要運行了該協議的服務器端(daemon),當前服務器就變爲郵件服務器,能夠接收電子郵件。post
驗證 Email 郵箱的基本思路以下。google
- 找到郵箱所在域名的 SMTP 服務器
- 鏈接該服務器
- 詢問有沒有該郵箱
- 若是服務器返回 250 或 251 狀態碼,郵箱就是真的;若是返回 5xx(500~599),就是假的。
注意,即便服務器確認郵箱是真的, 也不表明郵件必定會發送到該郵箱,更不表明用戶必定會讀到該郵件。spa
下面經過一個例子,演示如何驗證test@gmail.com
這個郵箱。.net
首先,須要查找gmail.com
的 MX 記錄。它指向真正處理郵件的那臺服務器。
$ nslookup
>
輸入nslookup
命令後,會提示一個大於號,表示等待用戶進一步輸入。
> set q=mx > gmail.com
上面代碼中,set q=mx
設定查詢的是 MX 記錄,第二行輸入要查找的域名,結果返回了5條 MX 記錄。
Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: gmail.com mail exchanger = 20 alt2.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 = 5 gmail-smtp-in.l.google.com. gmail.com mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com
是很大的郵件服務商,因此會有多條記錄,通常的域名只有一條。若是這一步查不到 MX 記錄,該郵箱確定是假的。
除了本身執行nslookup
,也可使用線上服務(1,2,3)。更多 DNS 的介紹,請參考《DNS 原理入門》。
知道了郵件服務器的地址,就能夠與它創建 TCP 鏈接了。SMTP 協議的默認端口是25。使用 Telnet 或 Netcat 命令,均可以鏈接該端口。
$ telnet gmail-smtp-in.l.google.com 25 # 或者 $ nc gmail-smtp-in.l.google.com 25
服務器返回220
狀態碼,就表示鏈接成功。
220 mx.google.com ESMTP f14si7006176pln.607 - gsmtp
接下來,就可使用 SMTP 協議的各類命令與郵件服務器交互了。
SMTP 協議規定,鏈接成功後,必須向郵件服務器提供鏈接的域名,也就是郵件將從哪臺服務器發來。
假定從mail@example.com
向test@gmail.com
發送郵件,這裏要提供的域名就是www.10rz.net
。
HELO exampl.com
郵件服務器返回狀態碼250
,表示響應成功。
250 mx.google.com at your service
不過,HELO
命令如今比較少用,通常都使用EHLO
命令。
EHLO example.com
郵件服務器收到EHLO
命令之後,不只會返回250
狀態碼,還會返回本身支持的各類擴展的列表。
250-mx.google.com at your service, [114.84.160.153] 250-SIZE 157286400 250-8BITMIME 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-CHUNKING 250 SMTPUTF8
而後,鏈接者要使用MAIL FROM
命令,向郵件服務器提供郵件的來源郵箱。
MAIL FROM:<mail@example.com>
上面代碼表示,鏈接者將從mail@example.com
向郵件服務器發送郵件。郵件服務器返回250
狀態碼,表示響應成功。
250 2.1.0 OK h10si3194349otb.59 - gsmtp
SMTP 是一個很簡單的協議,自己沒有規定如何驗證郵件的來源,也就是說,不驗證郵件是否真的從mail@example.com
發來,因此致使了後來垃圾郵件氾濫。爲了控制垃圾郵件,許多郵件服務器會用本身的方法驗證郵件地址,下面就是其中的一些方法。
- example.com 是否有 MX 記錄
- example.com 是否能夠 Ping 通
- 是否存在 postmaster@example.com 這個郵箱
- 發起鏈接的 IP 地址是否在黑名單之中
- IP 地址的反向 DNS 解析,是否指向一個郵件服務器
最後一步就是使用RCPT TO
命令,驗證郵件地址是否存在。
RCPT TO:<test@gmail.com>
郵件服務器返回了550
狀態碼,表示該 Email 地址不存在。
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 https://support.google.com/mail/?p=NoSuchUser p34si3372771otp.228 - gsmtp
若是查詢的是一個真實的 Email 地址,郵件服務器就會返回250
狀態碼。
RCPT TO:<yifeng.ruan@gmail.com> 250 2.1.5 OK p34si3372771otp.228 - gsmtp
通常來講,狀態碼 250 和 251 都表示郵箱存在,狀態碼 5xx 表示不存在,神馬影院其餘狀態碼(主要是 4xx)則表明沒法確認。
RCPT TO:<xxx@censored.pl> 451 Temporary local problem - please try later
驗證完成後,使用QUIT
命令關閉 TCP 鏈接。
QUIT
221 2.0.0 closing connection p34si3372771otp.228 - gsmtp