近期发现有些“路人”途经小站时,注册完那东西就跑(我承认这小地方确实没什么能吸引眼球的 #受虐滑稽 )。
这不是关键,关键是有人提问题,可是没留邮箱;这除非小伙伴常来看看,不然是无法获得回复提示的。于是,为此加了登陆时强制提示没邮件地址的小伙伴填写邮箱,但有小伙伴填了虚构的不存在的邮件地址,所以想加强邮件验证(本篇重点 #太开心 )。分析原因,可能是不想留下个人信息,所以又加了一个删除自己账户的功能(在个人资料页可见)。但邮件验证并不简单,想在网上找现成的却没有(都是一些半残的老旧代码 #摊手 ),所以参考这些代码自己搞了一个,凑合用 #酷 。
这不是关键,关键是有人提问题,可是没留邮箱;这除非小伙伴常来看看,不然是无法获得回复提示的。于是,为此加了登陆时强制提示没邮件地址的小伙伴填写邮箱,但有小伙伴填了虚构的不存在的邮件地址,所以想加强邮件验证(本篇重点 #太开心 )。分析原因,可能是不想留下个人信息,所以又加了一个删除自己账户的功能(在个人资料页可见)。但邮件验证并不简单,想在网上找现成的却没有(都是一些半残的老旧代码 #摊手 ),所以参考这些代码自己搞了一个,凑合用 #酷 。
1.探索中的意外:
在使用telnet过程中发现使用QQ邮箱时,在输入隶属于QQ邮箱的邮件接收方后,服务器会自动检索是否存在这个用户,并返回完全正确的信息;网易也是。
于是,想到:是不是每个邮件服务器都会在 用户输入 所属域为 这个邮件服务器的邮件 时,执行用户存在性检索操作。(只能但这个结论正确了,不然玩儿什么 #受虐滑稽 )
2.思路:
(1)判断邮箱基本格式是否正确
(2)邮箱的域名后缀是否有效
(3)通过smtp判断账户有效性
已知可以此判断的邮箱:QQ邮箱(包括域名邮箱),网易邮箱
已知不可以此判断的邮箱:Gmail
已知不可以此判断的邮箱:Gmail
3.处理:
(1)处理最外部:
//对验证结果进行处理,存在返回true,否则返回false if (validate_email($email)) echo 'ok<br />'; else echo 'failed<br />';
(2)验证格式:
$exp = "/([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[.][a-z]{2,3}([.][a-z]{2})?/i"; $check_format = preg_match($exp,$email);
(3)对格式验证结果进行判断:
if ($check_format) { //进入域名MX记录可用性判断 }else{ return false; }
(4)对域名MX记录可用性进行判断:
$email0 = explode("@",$email); $email1 = array_pop($email0); $email2 = checkdnsrr($email1,"MX"); if ($email2) { //QQ域名邮箱 $emailmx = dns_get_record($email1,DNS_MX); $emailmx_target = $emailmx[0]['target']; if ($emailmx_target == 'mxdomain.qq.com') $email1 = 'qq.com'; //进入邮箱用户名有效性判断 }else{ return false; }
(5)对账户可用性进行判断:
根据邮件所属域进行检查
switch ($email1) { case 'qq.com': check_user($qquser,$qqpass,'smtp.qq.com',25,$email);//调用QQ邮箱用户存在性检测函数 break; case '163.com': check_user($wyuser,$wypass,'smtp.163.com',25,$email);//调用网易邮箱存在性检测函数 break; default: return true; }
(6)定义邮箱用户存在性检测函数:
function check_user($user,$pass,$smtp_server,$port = 25,$mail) { /** * 通过邮件服务器 验证邮箱是否存在 * 这里要明白的是用户名是 带域名的:aaa@163.com *$mail = '待测邮箱'; *$user = '已有用户'; *$pass = '已有用户的秘码'; *$smtp_server = '相对应的邮件服务器'; *$port = 25; */ $handle = fsockopen($smtp_server, $port); if (!$handle) return false; $mes = fgets($handle); //echo $mes.'<br>'; if (!$mes) { fclose($handle); return false; } $status = explode(" ",$mes); if ($status[0] != 220) { //链接服务器失败 fclose($handle); return false; } fwrite($handle, 'HELO mystore'."\r\n"); //表明身份,这里的mystore是随便写的 $mes = fgets($handle).'<br>'; //echo $mes; if (!$mes) { fclose($handle); return false; } $status = explode(" ",$mes); if ($status[0] != 250) { //服务器HELO失败 fclose($handle); return false; } fwrite($handle, 'AUTH LOGIN'."\r\n"); $mes = fgets($handle); //echo $mes.'<br>'; if (!$mes) { fclose($handle); return false; } $status = explode(" ",$mes); if ($status[0] != 334) { //请求验证登陆失败 fclose($handle); return false; } fwrite($handle,base64_encode($user)."\r\n"); $mes = fgets($handle); //echo $mes.'<br>'; if (!$mes) { fclose($handle); return false; } $status = explode(" ",$mes); if ($status[0] != 334) { //验证用户名失败 fclose($handle); return false; } fputs($handle,base64_encode($pass)."\r\n"); $mes = fgets($handle); //echo $mes.'<br>'; if (!$mes) { fclose($handle); return false; } $status = explode(" ",$mes); if ($status[0] != 235) { //验证密码失败 return false; } fputs($handle,'MAIL FROM:<'.$user.">\r\n"); $mes = fgets($handle); //echo $mes.'<br>'; fwrite($handle, 'RCPT TO:<'.$mail.">\r\n"); $mes = fgets($handle); fclose($handle); //echo $mes.'<br>'; $status = explode(" ",$mes); if ($status[0] != 250) { //echo '邮箱不存在<br>'; //用户不存在 return false; } else { return true; } }
3.注册qq邮箱与网易邮箱,并填入账号密码,进行调用