如何验证 Email 地址:SMTP 协议入门教程
http://www.ruanyifeng.com/blog/2017/06/smtp-protocol.html
作者: 阮一峰
日期: 2017年6月25日
Email 是最常用的用户识别手段。
开发者常常需要验证邮箱的真实性。一般的方法是,注册时向该邮箱发出一封验证邮件,要求用户点击邮件里面的链接。
但是很多时候(比如要搞邮件营销时),拿到的是成千上万现成的 Email 地址,不可能通过回复确认真实性,这时该怎么办呢?
答案就是使用 SMTP 协议。本文将介绍如何通过该协议验证邮箱的真假。
另外,结尾处还有一则移动端 H5 开发的培训消息,欢迎关注。
一、SMTP 协议简介
SMTP 是"简单邮件传输协议"(Simple Mail Transfer Protocol)的缩写,基于 TCP 协议,用来发送电子邮件。
只要运行了该协议的服务器端(daemon),当前服务器就变为邮件服务器,可以接收电子邮件。
验证 Email 邮箱的基本思路如下。
- 找到邮箱所在域名的 SMTP 服务器
- 连接该服务器
- 询问有没有该邮箱
- 如果服务器返回 250 或 251 状态码,邮箱就是真的;如果返回 5xx(500~599),就是假的。
注意,即使服务器确认邮箱是真的, 也不代表邮件一定会发送到该邮箱,更不代表用户一定会读到该邮件。
二、查找域名的 MX 记录
下面通过一个例子,演示如何验证test@gmail.com
这个邮箱。
首先,需要查找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 连接
知道了邮件服务器的地址,就可以与它建立 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 协议的各种命令与邮件服务器交互了。
四、HELO 命令和 EHLO 命令
SMTP 协议规定,连接成功后,必须向邮件服务器提供连接的域名,也就是邮件将从哪台服务器发来。
假定从mail@example.com
向test@gmail.com
发送邮件,这里要提供的域名就是example.com
。
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 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
命令,验证邮件地址是否存在。
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
七、参考链接
(正文完)
如何验证 Email 地址:SMTP 协议入门教程的更多相关文章
- javascript使用正则表达式验证Email地址
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]
WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...
- python3之模块SMTP协议客户端与email邮件MIME对象
转载自https://www.cnblogs.com/zhangxinqi/p/9113859.html 阅读目录 1.smtplib模块的常用类与方法 2.处理邮件MIME 3.实例 (1)使用HT ...
- 用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学
首发于:用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=428 给软 ...
- 【OpenLayers】入门教程地址
[OpenLayers]入门教程地址: 点击进入 http://anzhihun.coding.me/ol3-primer/index.html 简书地址 : http://www.jians ...
- Email地址验证
<script>function validateForm(){ var x=document.forms["myForm"]["email"].v ...
- php中的curl使用入门教程和常见用法实例
摘要: [目录] php中的curl使用入门教程和常见用法实例 一.curl的优势 二.curl的简单使用步骤 三.错误处理 四.获取curl请求的具体信息 五.使用curl发送post请求 六.文件 ...
- 基于公网smtp协议实现邮件服务器
刚开始做邮件服务器开发,一切都是茫然的.在书上网上都很难找到一套完整的邮件服务器开发教程.在个人的摸索中碰到了很多蛋疼得问题.现终于完成了,将我的开发经验分享给大家. 开发环境:vs2012 mfc ...
- 《JavaScript语言入门教程》记录整理:运算符、语法和标准库
目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...
随机推荐
- JavaScript对数组的处理(一)
数组创建 JavaScript中创建数组有两种方式,第一种是使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组 var arr2 = new Array( ...
- Mac mysql 解决中文乱码
Mac mysql 解决中文乱码问题 出现"???"之类的无法识别的乱码 到/etc目录下自己建一个my.cnf文件(需要最高权限,使用sudo su),然后写入内容: [clie ...
- Objective-C语法之NSSortDescriptor
main.m #import <Foundation/Foundation.h> #import "Person.h" /** NSSortDescriptor 可以实 ...
- SharePoint PowerShell创建一个GUID
在编辑SharePoint后台XML架构时常需要在ID属性上填写一个GUID (Globally Unique Identifiers 全局唯一标识的简称): 我们可以打开SharePoint管理控制 ...
- winform下通过webclient使用非流方式上传(post)数据和文件
这两天因为工作的需要,需要做一个winform上传数据到服务器端的程序.当时第一个想法是通过webservice的方式来实现,后来觉得麻 烦,想偷懒就没有用这样的方式,http的post方式变成了第一 ...
- 新浪股票接口AndroidSDK
昨天想到一个点子,需要访问股票行情.于是在网上搜了一下免费的股市行情的接口.发现新浪股票的数据接口比较稳定,于是就用它了. 网上对于新浪股票的数据接口介绍比较详细,并且实现也很简单,所以花了一下午就基 ...
- 将nosetests的echo结果保存到本地文件
nose是很好用的python 测试框架. 但是一直很纠结如何将结果保存到本地.采用nosetests -h查看相关的options,找到一个xunit的东西,似乎可以实现功能. 测试结果: 可见,已 ...
- MathType输入框怎么调整
在用MathType编辑公式编辑器时,除了可以对MathType工具栏的显示比例进行调整以外,还可以对编辑时的输入框进行调整.这样在编辑的过程中,工具栏可以看得很清楚,同时框输入框也可以看得很清楚,这 ...
- Three-js 创建第一个3D场景
1.一个场景至少需要的三种类型组件 相机/决定哪些东西将在屏幕上渲染 光源/他们会对材质如何显示,以及生成阴影时材质如何使用产生影响 物体/他们是在相机透视图里主要的渲染队形:方块.球体等 ...
- geoserver 地图性能和缓存
1.什么是GeoWebCache GeoWebCache是地图缓存软件公司成员开发的一个基于java的开源项目.和其他的缓存系统相似,它作为一个客户端和地图服务的代理.它可以单独部署,适用于任何基于W ...