65.9K
CodeProject 正在变化。 阅读更多。
Home

应用程序的端到端电子邮件地址验证

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.26/5 (92投票s)

2003年10月11日

CPOL

4分钟阅读

viewsIcon

950185

downloadIcon

12832

在本文中,我们将讨论一种非常简短且全面的技术,用于验证用户注册网络账户时提供的电子邮件地址。

 引言 

电子邮件已成为我们日常生活不可或缺的一部分。即使在我们开发的 Web 应用程序中,网站/应用程序与用户之间信息交换的主要方式也是电子邮件地址。为此,有些网站有一个主电子邮件地址和一个备用电子邮件地址(如果主地址出现问题,将发送信息给备用地址)。

在任何期望有各种用户访问和注册的网络门户和/或应用程序中,都应注意验证电子邮件地址,因为这是用户与网站之间进行通信的主要媒介。

范围:  

此实用程序的范围是双重的

  1. 电子邮件地址的软语法验证。 
  2. 深度网络检查,其中联系电子邮件服务器以检查地址是否存在。 

验证 

对电子邮件地址进行非常初步的验证是通过分析地址的模式。这非常直接,我们可以定义一个正则表达式来完成这项工作。

以下 C# 中的正则表达式方法将告诉您,传入的电子邮件地址是否在语法上有效。请注意,这仅验证语法有效性,而不验证电子邮件地址是否存在。

public static bool isEmail(string inputEmail)
{
   inputEmail  = NulltoString(inputEmail);
   string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
         @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + 
         @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
   Regex re = new Regex(strRegex);
   if (re.IsMatch(inputEmail))
    return (true);
   else
    return (false);
} 

我们可以尝试的下一个验证级别是与 SMTP 服务器进行协商并进行验证。一些邮件服务器会响应 VRFY 和/或 RCPT SMTP 命令,以判断电子邮件地址是否有效。但是,对于严格配置为不披露不存在地址的服务器,它们将始终承认其域内的任何无效地址,并在稍后自行将其退回。我们需要解决以下各项。

通过 SMTP 网络连接进行验证

string[] host = (address.Split('@'));
string hostname = host[1];
     
IPHostEntry IPhst = Dns.Resolve(hostname);
IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], 25);
Socket s= new Socket(endPt.AddressFamily, 
        SocketType.Stream,ProtocolType.Tcp);
s.Connect(endPt); 

如果域名无效,此步骤将抛出异常,这样您就可以标记电子邮件地址无效。

通过 SMTP 握手进行验证

如果域名没问题,我们可以尝试与实际服务器进行握手,以找出电子邮件地址是否有效。也许,此时,我想建议一个应用程序如何像 Peter 在 此处(EggHeadCafe)解释的那样与 SMTP 服务器进行协商。无论如何,我们不需要全部代码。 

我们可以检查 SMTP 协商的每个部分,例如 MAIL FROM 和 RCPT TO 以及可选的 VRFY SMTP 命令。 

如果域或发件人地址被禁止或不在 SMTP 服务器的允许列表中,MAIL FROM 可能会失败。允许 VRFY 命令的邮件服务器将让您了解电子邮件地址是否有效。

我的代码段

由于我们有类似的要求,EggHeadCafe 真的很有用,我想与其他可能遇到类似要求的用户分享代码片段。

string[] host = (address.Split('@'));
string hostname = host[1];

IPHostEntry IPhst = Dns.Resolve(hostname);
IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], 25);
Socket s= new Socket(endPt.AddressFamily, 
             SocketType.Stream,ProtocolType.Tcp);
s.Connect(endPt);

//Attempting to connect
if(!Check_Response(s, SMTPResponse.CONNECT_SUCCESS))
{                
    s.Close();
    return false;
}

//HELO server
Senddata(s, string.Format("HELO {0}\r\n", Dns.GetHostName() ));
if(!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
{
    s.Close();
    return false;
}

//Identify yourself
//Servers may resolve your domain and check whether 
//you are listed in BlackLists etc.
Senddata(s, string.Format("MAIL From: {0}\r\n", 
     "testexample@deepak.portland.co.uk"));
if(!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
{
    s.Close();
    return false;
}


//Attempt Delivery (I can use VRFY, but most 
//SMTP servers only disable it for security reasons)
Senddata(s, address);
if(!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
{
    s.Close();
    return false;
}
return (true);

Check_ResponseSendData 在原始源代码中可用,您可以从那里下载。但是,您可能需要阅读相关的许可协议,以保留代码中的版权声明。由于这只是一个介绍该想法的代码片段,因此只提到了相关的代码区域。

临时验证

如果网络条件良好,一切都会顺利。但是,可能存在临时网络问题,阻碍连接。如果您预计您的主机可能速度很慢,那么您可以向电子邮件地址发送一个虚拟链接,并且只有当用户访问该地址并单击链接后才激活帐户。否则,您可以通过在 Web 应用程序中设置一个计划任务来停止帐户激活步骤,并定期回收垃圾帐户。 

DNS 实用程序 

特别感谢并归功于 Heijden 的 DNS 实用程序,该实用程序被用于在应用程序中查找 Mx 服务器。这为应用程序提供了更清晰的关注点分离。 

总结...

事实上,我希望许多 Web 开发人员会需要类似的验证例程,以确保电子邮件地址有效,我真的希望上述提示会对他们有所帮助。感谢 Peter,您的文章真的帮助了我,我希望您的文章和我上面分享的所有提示,能真正帮助到更多有类似需求的开发人员解决问题。 

© . All rights reserved.