【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

时间:2022-09-24 12:57:46

提示:阅读本文需提前了解的相关知识

1、电子邮件协议(http://baike.baidu.com/view/2367542.htm

2、阿里云邮件推送(https://www.aliyun.com/product/directmail

3、EDM(电子邮件营销)(http://baike.baidu.com/subview/1212416/8602812.htm

4、SendCloud邮件服务(http://sendcloud.sohu.com/

阅读目录结构

引:

一、需求分析

二、功能设计

三、详细实现步骤

四、总结与思考

 


引:

我们会发现,越来越多的互联网应用和企业级应用,开始使用邮件验证码验证替代邮件链接验证,例如下图:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

又例如:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

当然,也有更多的应用使用了漂亮的HTML代码来装饰邮件,例如:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

又例如:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

我想,一个优秀的互联网应用或者个体经营的站长站点,如果在注册、身份证验证、信息推送等功能上,加上如上效果的邮件服务,一定能带来更加优质的用户体验

而邮件服务也不是现在才有,我们可以回顾一下发展历史

很多站长应该都记得,在例如Discuz、WordPress等CMS中,都可以配置SMTP信息,开通了163等邮箱的SMTP功能就可以填入账号密码,从而达到发送邮件的功能。

很多企业在若干年前,也热衷于使用大型如ExchangeServer,中小型如UMail等软件搭建自己的企业邮件服务系统。

但是随着互联网的发展,伴随着QQ等邮件服务商的走红,传统的国外那一套邮件规则和秩序已经发生了改变,有时候就算你有很多IP,做了反向解析,在Spamhaus白名单,又或者虚拟了不同的helo域,QQ邮箱还是照拦不误,最终还是得单独花钱向国内外各大ESP购买独立通道

在这种情况下,自建邮局系统或者邮件SMTP服务,就显得得不偿失了,所以一方面各大企业邮箱服务越做越好,得到企业的认可,另一方面,国内外如SendGrid,SendCloud等第三方邮件PUSH服务商也逐渐做大,他们用更专业的手段,去解决通道、白名单、信誉度等各种邮件服务问题,而客户只需要通过SMTP协议或者封装的API接口,就可以非常便捷的给用户发送邮件

就我所知,目前国内做的最好的当属搜狐的SendCloud,但是SendCloud发展了这么多年,也越来越复杂和专业,我认为更适合有大型EDM需求的应用使用,作为中小企业和创业者以及站长,首推依然是阿里云的邮件推送服务,一如既往秉持阿里云的特点:使用傻瓜,上手快速,文档俱全,但漏洞和问题多多不过作为AWS的追赶者,能在短时间内快速实现这些应用级功能,也算是值得鼓励的。因此下面也基于阿里云邮件推送服务,来实现一个自己的邮件验证与推送体系

一、需求分析

做任何事情,顶层设计非常重要,优秀的设计往往让以后的事情事半功倍,所以在设计整个邮件验证与推送体系前,我们先看看有哪些功能是希望能够实现的

  • 支持邮件发送验证码邮件营销推送
  • 能够通过开发在程序逻辑或者管理界面中自动触发发送
  • 能够支持HTML的邮件内容,而HTML内容能够随时随地进行修改,方便美工和开发去调整
  • 验证类邮件能够支持IP统计、次数统计,能够进行时间限制、防止恶意发送
  • 推送类邮件能够支持统计发送数量、发送成功率等反馈数据。
  • 推送类邮件,用户可以退订。

当然,最重要的,验证邮件要能在5-10秒内发送成功,到达率高

二、功能设计

经过以上需求分析,可以明确出以下一些关键的设计思路

1、需要设计模板功能。通过模板功能来支持HTML邮件内容以及随时可更新替换的要求,通过模板里的关键词参数设计,来达到验证码、用户名、营销内容的动态输入。

2、需要设计一个验证码相关表。用来支撑邮件验证码校验、请求限制等功能。

3、需要设计一个发送记录相关表。记录所有发送记录,用于统计和分析。

4、管理后台尽量界面化管理。用户管理、邮件模板配置、发送记录查询等基本支撑功能,在后台尽量以界面化实现管理。

5、将企业邮局和邮件推送服务分开。以域名XXX.com为例,一般企业邮局地为zhangsan@XXX.com,邮件服务不宜以XXX.com为域,会和企业邮局服务相互干扰(也不是完全不可能,只是配置起来很麻烦),应当增加一个二级域名,例如mail.XXX.com,邮件服务地址就是service@mail.XXX.com

整体功能架构图如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

三、详细实现步骤

正好手上有个网站,含有注册邮件验证功能,那就基于这个网站的开发,一步一步的讲解一下详细的实现步骤

最终实现效果如下:

网站域名是:alphams.cn,地址为 https://www.alphams.cn,用户注册地址为https://www.alphams.cn/Register

官方企业邮箱域是@alphams.cn,客服邮件地址为:kefu@alphams.cn

在阿里云申请的邮件服务域为:@mail.alphams.cn,服务邮件地址为:service@mail.alphams.cn

具体的实现步骤为:

1、注册阿里云企业邮箱免费版,实现客服邮件地址

我们的企业邮局服务使用了阿里云企业邮箱免费版。(吐槽一下,竟然要转发微博才能注册还捆绑消费6元邮件推送)

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

支付成功后,可以在企业邮箱列表中看到

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

下面继续设置解析,可以到帮助页面看到如何设置解析

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

前往域名解析处进行解析设置

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

解析后,企业邮箱生效,进行管理员用户密码初始化

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

使用管理员账号进入 https://qiye.aliyun.com/ 

继续设置安全问题并绑定手机号

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

成功进入后继续添加客户账号

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

至此,企业邮局账号添加成功,到Foxmail中进行登录。

2、配置阿里云邮件服务

首先要添加一个发信域名

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这里我们也可以注意到,阿里云也提示不要添加企业邮箱域名,这和我们之前设计中的思路一致,这里我们添加的域名是 mail.alphams.cn

然后阿里云提示需要配置一些解析信息,从而生效域名

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

下面前往阿里云的域名解析中进行设置

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

设置好了以后回到刚才的页面进行验证

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这样,域名就添加成功了

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

下面继续添加发信地址

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这里我们可以看到,发信账号如我们之前所说,是service@mail.alphams.cn

发信类型选择了批量邮件这里有个疑问,在实测中发现,阿里云这个推送服务有触发邮件和批量邮件,触发邮件类型偶尔会发不出去或者接收不到,不知道原因是什么,有深入研究的人感谢告知我一下

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这时候回信地址还未通过验证,我们点击验证回信地址,然后前往之前申请的QQ企业邮箱中,来验证

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这样就进行了验证

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这时候还需要设置一下SMTP密码,我们设置为XXX

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这里特别需要注意的是阿里云的官方说明

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

发信域名在创建之前要仔细,因为不能给删除和修改。

这样,阿里云邮件服务的配置就完成了。

SMTP服务地址为:smtpdm.aliyun.com,SMTP账号就是service@mail.alphams.cn,密码就是刚才设置的密码

到这一步为止,已经可以为很多站长网站的邮件服务提供支撑了,在一些CMS里面直接配置入SMTP信息即可使用

但是,网站和应用大部分都是独立开发,我们更需要设计自己的邮件发送和功能处理体系,因此下面我们继续

3、用户注册页面的准备工作

具体的页面编码和程序逻辑因为非今天所讲重点,所以这里省略若干字以及若干代码,把主要的步骤列出来,源码可邮件找我要:

由于要加入邮件地址的验证,所以先对注册页面的完整流程进行设计,逻辑图如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

其中,为了增强用户体验,先验证邮件地址,再输入用户名,而这种里面的关联和强逻辑用一个注册会话表来进行控制

注册会话表结构如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

临时验证成功的邮件地址,存入会话表,并向客户端反回一个会话编号,最终完成注册时,需要用户名密码连同这个会话编号一起传入后台验证注册

接下来就是邮件验证表的设计

这个表既要能支持没有用户状态的验证,例如注册验证,又要能支持用户运行时的验证,例如修改密码验证等。

表结构如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

其中渠道为具体的使用场景,状态和过期时间两个字段用来双重控制有效性,预留的两个参数,用于存储用户编号、注册会话编号等额外的数据

当然,也少不了用户表,因为这里并没有什么特殊的用户场景,所以用户表较为简单,结构如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

4、邮件模板的设计

接下来就进入具体的开发,在开发中,肯定会用到对邮件的发送,在我们这个设计的体系里面,最上面也说了,需要设计模板机制,那么我们就先设计邮件模板功能

具体的功能架构为:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

这里设计了最简单的模板功能,主要思路即数据库存储HTML模板内容,参数直接放入HTML代码中,在开发时进行替换

下面是邮件模板表的设计,表结构如下:

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

在后端对模板进行增删改查管理,省略代码若干,最终效果如下:

先构建一个用于新用户注册的HTML模板

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

然后在管理界面添加信息和HTML代码

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

然后添加成功

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

5、邮件发送的技术准备

通过阿里云的技术文档可以知道,阿里云邮件服务的调用方式有三种

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

原本准备使用API接口进行封装,但是最近太忙了,所以先使用STMP接口方式进行了一次封装,主要代码如下:

实体:

/// <summary>
/// 邮件直推请求
/// </summary>
public class AliyunEMailDirectPushRequest
{
/// <summary>
/// 目标邮件地址列表
/// </summary>
public Dictionary<String, String> AimAddressList { get; set; }

/// <summary>
/// 来源邮件地址
/// </summary>
public KeyValuePair<String, String> FromAddress { get; set; }

/// <summary>
/// 回复邮件地址列表
/// </summary>
public Dictionary<String, String> ReplyAddressList { get; set; }

/// <summary>
/// 邮件标题
/// </summary>
public String Subject { get; set; }

/// <summary>
/// 邮件文本
/// </summary>
public String Text { get; set; }

/// <summary>
/// 邮件HTML
/// </summary>
public String HTML { get; set; }

/// <summary>
/// 类型
/// </summary>
public Int32 Type { get; set; }

/// <summary>
/// SMTP用户名
/// </summary>
public String SMTPUserName { get; set; }

/// <summary>
/// SMTP密码
/// </summary>
public String SMTPPassword { get; set; }
}

/// <summary>
/// 邮件直推响应
/// </summary>
public class AliyunEMailDirectPushResponse
{
/// <summary>
/// 推送结果
/// </summary>
public Int32 Result { get; set; }

/// <summary>
/// 推送结果消息
/// </summary>
public String ResultMessage { get; set; }
}

 

发送业务代码:

/// <summary>
/// 邮件直接推送
/// </summary>
/// <param name="String"></param>
/// <returns></returns>
public static AliyunEMailDirectPushResponse EMailDirectPush(AliyunEMailDirectPushRequest _Request)
{
AliyunEMailDirectPushResponse MyReturn = new AliyunEMailDirectPushResponse();
MailMessage MyMailMessage = new MailMessage();
//填充目标邮件地址
foreach (var e in _Request.AimAddressList)
{
MyMailMessage.To.Add(new MailAddress(e.Key, e.Value));
}
//填充来源邮件地址
MyMailMessage.From = new MailAddress(_Request.FromAddress.Key, _Request.FromAddress.Value);
//填充回复邮件地址
foreach (var e in _Request.ReplyAddressList)
{
MyMailMessage.ReplyToList.Add(new MailAddress(e.Key, e.Value));
}
// 邮件主题
MyMailMessage.Subject = _Request.Subject;
// 邮件正文内容

String Text = _Request.Text;
String HTML = _Request.HTML;
if (_Request.Type == 1)
{
//文本发送方式
MyMailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(Text, null, MediaTypeNames.Text.Plain));
}
if (_Request.Type == 2)
{
//HTML发送方式
MyMailMessage.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(HTML, null, MediaTypeNames.Text.Html));
}
//邮件推送的SMTP地址和端口
SmtpClient MySmtpClient = new SmtpClient("smtpdm.aliyun.com", 25);
// 使用SMTP用户名和密码进行验证
System.Net.NetworkCredential MyNetworkCredential = new System.Net.NetworkCredential(_Request.SMTPUserName, _Request.SMTPPassword);
MySmtpClient.Credentials = MyNetworkCredential;
MySmtpClient.Timeout = 5000;//设置5秒超时
try
{
MySmtpClient.Send(MyMailMessage);
MyReturn.Result = 1;
MyReturn.ResultMessage = "发送成功";
return MyReturn;
}
catch (Exception e)
{
MyReturn.Result = -1;
MyReturn.ResultMessage = e.Message;
return MyReturn;
}
}

6、邮件验证码生成与发送的实现

主要代码如下:

/// <summary>
/// 创建注册邮件验证
/// </summary>
/// <param name="_Request"></param>
/// <returns></returns>
private DWebAccountCreateRegisterEMailVerifyResponse CreateRegisterEMailVerify(DWebAccountCreateRegisterEMailVerifyRequest _Request, HttpRequestMessage _HttpRequest)
{
DWebAccountCreateRegisterEMailVerifyResponse MyResponse = new DWebAccountCreateRegisterEMailVerifyResponse();
DWebMySQLDataContexter CheckQueryDataContexter = CreateNewDataContexter();
//首先检查是否存在邮件
var UserCheckQuery = CheckQueryDataContexter.ams_user_table.Where(e => e.AUT_EMAILADDRESS == _Request.EMailAddress);
if (UserCheckQuery.Count() > 0)
{
MyResponse.SetResult(-1, "邮件已经存在");
return MyResponse;
}
else
{
//再检查和最近一次的发送是否已经超过1分钟了
DateTime CheckDateTime = DateTime.Now.AddMinutes(4);//增加4分钟
var VerifyCreateCheckQuery = CheckQueryDataContexter.ams_email_verify_table.Where(e => e.AEVT_EMAILADDRESS == _Request.EMailAddress && e.AEVT_EXPIRETIME >= CheckDateTime);
if (VerifyCreateCheckQuery.Count() > 0)
{
MyResponse.SetResult(-2, "一分钟内只能发送一次邮件,请稍后再试!");
return MyResponse;
}
else
{
//将之前发送的验证码全部失效
DWebMySQLDataContexter UpdateQueryDataContexter = CreateNewDataContexter();
var EMailVerifyClearUpdateQuery = UpdateQueryDataContexter.ams_email_verify_table.Where(e => e.AEVT_EMAILADDRESS == _Request.EMailAddress);
var RegisterSessionClearUpdateQuery = UpdateQueryDataContexter.ams_register_session_table.Where(e => e.ARST_EMAILADDRESS == _Request.EMailAddress);
foreach (var e in EMailVerifyClearUpdateQuery)
{
e.AEVT_STATE = -1;//表示失效
}
foreach (var e in RegisterSessionClearUpdateQuery)
{
e.ARST_STATE = -1;//表示失效
}
try
{
UpdateQueryDataContexter.SaveChanges();
//下面发起一个新的验证
DWebMySQLDataContexter NewTableDataContexter = CreateNewDataContexter();
//生成验证码
Random MyRandom = new Random();
String VerifyCode = MyRandom.Next(1000, 10000).ToString();//获得一个4位随机码

DateTime NowDateTime = DateTime.Now;
ams_email_verify_table TempEMailVerifyTable = new ams_email_verify_table();
TempEMailVerifyTable.AEVT_ID = BLHelper.NewGuid();
TempEMailVerifyTable.AEVT_CHANNEL = 1;//表示注册验证
TempEMailVerifyTable.AEVT_CHANNELDESCRIPTION = "注册验证";
TempEMailVerifyTable.AEVT_CREATETIME = NowDateTime;
TempEMailVerifyTable.AEVT_EXPIRETIME = NowDateTime.AddSeconds(300);//有效期300秒,5分钟
TempEMailVerifyTable.AEVT_EMAILADDRESS = _Request.EMailAddress;
TempEMailVerifyTable.AEVT_PARAMETER1 = "";//参数暂时为空
TempEMailVerifyTable.AEVT_PARAMETER2 = "";//参数暂时为空
TempEMailVerifyTable.AEVT_REQUESTIPNUMBERADDRESS = _HttpRequest.GetClientIPAddress().StringIPToNumberIP();//获得IP地址
TempEMailVerifyTable.AEVT_STATE = 1;//刚刚创建
TempEMailVerifyTable.AEVT_VERIFYCODE = VerifyCode;
TempEMailVerifyTable.AEVT_VERIFYTYPE = 1;//默认类型为1
//插入数据库
NewTableDataContexter.ams_email_verify_table.Add(TempEMailVerifyTable);
try
{
//保存
NewTableDataContexter.SaveChanges();
//下面就开启一个多线程发送邮件,然后返回获取成功,这里这样写不妥,但是为了用户体验,立即返回发送成功,就暂且相信阿里云的到达率吧

//下面在线程中发送邮件
Task TempTask;
TempTask = Task.Factory.StartNew(() =>
{

try
{
//下面继续用阿里云邮件推送发送邮件
//先读取邮件验证模板
String TaskVerifyCode = VerifyCode;
DWebMySQLDataContexter EMailTemplateDataContexter = CreateNewDataContexter();
String EMailTemplateUniqueIdentity = "NewRegisterVerify";
var EMailTemplateQuery = EMailTemplateDataContexter.ams_email_template_table.Where(e => e.AETT_UNIQUEIDENTITY == EMailTemplateUniqueIdentity).ToList();
if (EMailTemplateQuery.Count() > 0)
{
AliyunEMailDirectPushRequest MyRequest = new AliyunEMailDirectPushRequest();
//目标地址
MyRequest.AimAddressList = new Dictionary<String, String>();
MyRequest.AimAddressList.Add(_Request.EMailAddress, "AlphaMS门户注册邮箱【" + _Request.EMailAddress + "】");
//来源地址
MyRequest.FromAddress = new KeyValuePair<String, String>("service@mail.alphams.cn", "AlphaMS门户邮件服务");
//回复地址
MyRequest.ReplyAddressList = new Dictionary<String, String>();
MyRequest.ReplyAddressList.Add("kefu@alphams.cn", "AlphaMS门户客服");
String EMailHTML = EMailTemplateQuery.FirstOrDefault().AETT_CONTENT;
EMailHTML = EMailHTML.Replace("##EMailAddress##", _Request.EMailAddress);
EMailHTML = EMailHTML.Replace("##VerifyCode##", TaskVerifyCode);
MyRequest.HTML = EMailHTML;
MyRequest.Subject = "AlphaMS门户用户注册邮件验证";
MyRequest.Type = 2;//HTML方式发送邮件
MyRequest.SMTPUserName = "service@mail.alphams.cn";
MyRequest.SMTPPassword = "XXXXXX";
//下面发送
AliyunEMailDirectPushResponse TempAliyunEMailDirectPushResponse = AliyunControl.EMailDirectPush(MyRequest);
}
else
{
//模板不存在,也不报错
}
}
catch (Exception)
{
//在线程中不报错
}


});

MyResponse.SetResult(1, "发送成功");
return MyResponse;
}
catch (Exception NewTableSaveException)
{
return (DWebAccountCreateRegisterEMailVerifyResponse)SetExceptionError(MyResponse, NewTableSaveException, -5, "数据库错误");
}
}
catch (Exception UpdateStateSaveException)
{
return (DWebAccountCreateRegisterEMailVerifyResponse)SetExceptionError(MyResponse, UpdateStateSaveException, -5, "数据库错误");
}
}
}
}

7、验证码验证逻辑的实现

主要代码如下:

/// <summary>
/// 检查注册邮件验证码
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private DWebAccountCheckRegisterEMailVerifyCodeResponse CheckRegisterEMailVerifyCode(DWebAccountCheckRegisterEMailVerifyCodeRequest _Request, HttpRequestMessage _HttpRequest)
{
DWebAccountCheckRegisterEMailVerifyCodeResponse MyResponse = new DWebAccountCheckRegisterEMailVerifyCodeResponse();
//先检查是否有验证记录
DWebMySQLDataContexter CheckQueryDataContexter = CreateNewDataContexter();
DateTime NowDateTime = DateTime.Now;
var CheckQuery = CheckQueryDataContexter.ams_email_verify_table.Where(e => e.AEVT_EMAILADDRESS == _Request.EMailAddress && e.AEVT_STATE == 1 && e.AEVT_EXPIRETIME >= NowDateTime);
if (CheckQuery.Count() > 0)
{
String VerifyCode = CheckQuery.FirstOrDefault().AEVT_VERIFYCODE;
if (VerifyCode == _Request.VerifyCode)
{
//验证成功,设置这个验证失效
CheckQuery.FirstOrDefault().AEVT_STATE = -1;//设置失效

//所有的注册会话先失效
DWebMySQLDataContexter UpdateClearDataContexter = CreateNewDataContexter();
var ClearQuery = UpdateClearDataContexter.ams_register_session_table.Where(e => e.ARST_EMAILADDRESS == _Request.EMailAddress);
foreach (var e in ClearQuery)
{
e.ARST_STATE = -1;//全部失效
}


//下面就要新建一个注册会话
DWebMySQLDataContexter NewTableDataContexter = CreateNewDataContexter();
ams_register_session_table TempRegisterSessionTable = new ams_register_session_table();
TempRegisterSessionTable.ARST_ID = BLHelper.NewGuid();
CheckQuery.FirstOrDefault().AEVT_PARAMETER1 = TempRegisterSessionTable.ARST_ID;//和邮件验证建立起关联
TempRegisterSessionTable.ARST_CREATETIME = NowDateTime;
TempRegisterSessionTable.ARST_CLIENTIPNUMBERADDRESS = _HttpRequest.GetClientIPAddress().StringIPToNumberIP();
TempRegisterSessionTable.ARST_EMAILADDRESS = _Request.EMailAddress;
TempRegisterSessionTable.ARST_EXPIRETIME = NowDateTime.AddMinutes(10);//这个会话的有效期是10分钟
TempRegisterSessionTable.ARST_STATE = 1;//刚刚创建
NewTableDataContexter.ams_register_session_table.Add(TempRegisterSessionTable);
try
{
CheckQueryDataContexter.SaveChanges();
NewTableDataContexter.SaveChanges();
UpdateClearDataContexter.SaveChanges();
MyResponse.RegisterSessionID = TempRegisterSessionTable.ARST_ID;
MyResponse.SetResult(1, "验证成功");
return MyResponse;
}
catch (Exception DataSaveException)
{
return (DWebAccountCheckRegisterEMailVerifyCodeResponse)SetExceptionError(MyResponse, DataSaveException, -5, "数据库错误");
}
}
else
{
MyResponse.SetResult(-2, "验证码错误");
return MyResponse;
}
}
else
{
MyResponse.SetResult(-1, "已经过期,请重新获取验证码!");
return MyResponse;
}
}

8、前端注册页面的实现

//页面控制器
var PageControl = {
//注册初始化
RegisterInit: function () {
PageControl.NewRegisterSessionID = "";//重新清空会话编号
PageControl.EMailVerifyInit();
},
//邮件验证初始化
EMailVerifyInit: function () {
clearInterval(PageControl.GetVerifyCodeTimeLeft);
$("#AR_Register_EMailVerify_Container").show();
$("#AR_Register_EMailVerify_EMailAddress_TextBox").val("");
$("#AR_Register_EMailVerify_EMailAddress_TextBox").removeAttr("readonly");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").removeAttr("disabled");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").val("获取验证码");
$("#AR_Register_EMailVerify_Verify_Container").hide();
$("#AR_Register_EMailVerify_Verify_Code_TextBox").val("");
$("#AR_Register_UserInfo_Container").hide();
},
//获取验证码时间结束
GetVerifyCodeTimeLeft: null,
//创建邮件验证
CreateEMailVerify: function () {

//先隐藏起来
$("#AR_Register_EMailVerify_Verify_Container").hide();

//检查邮件地址输入
if ($("#AR_Register_EMailVerify_EMailAddress_TextBox").val() == "") {
AlphaMS.JSToolkit.Dialog.MessageBox("请输入邮件地址", function () {
$("#AR_Register_EMailVerify_EMailAddress_TextBox").focus();
});
return;
}

//检查邮件地址输入
if (!AlphaMS.JSToolkit.Valid.CheckMail($("#AR_Register_EMailVerify_EMailAddress_TextBox").val())) {
AlphaMS.JSToolkit.Dialog.MessageBox("请输入正确的邮件地址", function () {
$("#AR_Register_EMailVerify_EMailAddress_TextBox").focus();
});
return;
}

//AlphaMS业务逻辑请求
AlphaMS.JSToolkit.NET.BLRequest({
Debug: false,
//业务逻辑方法路由名称
FunctionRouteName: "AlphaMS.Portal.DWeb.Account.CreateRegisterEMailVerify",
//业务逻辑请求数据
BLRequestObject: {
//请求参数
//邮件地址
EMailAddress: $("#AR_Register_EMailVerify_EMailAddress_TextBox").val()
},
//SBS请求返回
BLResponse: {
//请求成功
Success: function (MyResponseObject) {
switch (MyResponseObject.ResultCode) {
case 1:
//注册成功
AlphaMS.JSToolkit.Dialog.MessageBox("验证码获取成功,有效期5分钟,请到邮箱中查收验证码并填入下面框中", function () {
$("#AR_Register_EMailVerify_Verify_Code_TextBox").focus();
});
$("#AR_Register_EMailVerify_EMailAddress_TextBox").attr("readonly", "readonly");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").attr("disabled", "disabled");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").html("重新获取(剩余60秒)");

var T = 60;//倒计时60秒
PageControl.GetVerifyCodeTimeLeft = setInterval(function () {
T = T - 1;
if (T == 0) {
//结束倒计时
clearInterval(PageControl.GetVerifyCodeTimeLeft);
$("#AR_Register_EMailVerify_EMailAddress_TextBox").removeAttr("readonly");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").removeAttr("disabled");
$("#AR_Register_EMailVerify_GetVerifyCode_Button").html("获取验证码");
} else {
$("#AR_Register_EMailVerify_GetVerifyCode_Button").html("重新获取(剩余" + T + "秒)");
}
}, 1000);

$("#AR_Register_EMailVerify_Verify_Container").show();


break;
case -1:
AlphaMS.JSToolkit.Dialog.MessageBox("邮件已经被其他用户使用,请换一个", function () {
$("#AR_Register_EMailVerify_EMailAddress_TextBox").focus();
});
break;
default:
AlphaMS.JSToolkit.Dialog.MessageBox(MyResponseObject.ResultMessage);
break;
}
}
}
}, ["Body"]);

},
//新注册会话编号
NewRegisterSessionID: "",
//检查邮件验证码
CheckEMailVerifyCode: function () {

//检查验证码输入
if ($("#AR_Register_EMailVerify_Verify_Code_TextBox").val() == "") {
AlphaMS.JSToolkit.Dialog.MessageBox("请输入收到的验证码", function () {
$("#AR_Register_EMailVerify_Verify_Code_TextBox").focus();
});
return;
}

//AlphaMS业务逻辑请求
AlphaMS.JSToolkit.NET.BLRequest({
Debug: false,
//业务逻辑方法路由名称
FunctionRouteName: "AlphaMS.Portal.DWeb.Account.CheckRegisterEMailVerifyCode",
//业务逻辑请求数据
BLRequestObject: {
//请求参数
//邮件地址
EMailAddress: $("#AR_Register_EMailVerify_EMailAddress_TextBox").val(),
//验证码
VerifyCode: $("#AR_Register_EMailVerify_Verify_Code_TextBox").val()
},
//SBS请求返回
BLResponse: {
//请求成功
Success: function (MyResponseObject) {
switch (MyResponseObject.ResultCode) {
case 1:
PageControl.NewRegisterSessionID = MyResponseObject.RegisterSessionID;
$("#AR_Register_EMailVerify_Container").hide();
$("#AR_Register_UserInfo_Container").show();
$("#AR_Register_EMail_TextBox").val($("#AR_Register_EMailVerify_EMailAddress_TextBox").val());
break;
case -1:
AlphaMS.JSToolkit.Dialog.MessageBox("验证码过期,请重新获取!", function () {
//初始化邮件验证
PageControl.EMailVerifyInit();
});
break;
case -2:
AlphaMS.JSToolkit.Dialog.MessageBox("验证码错误,请重新输入", function () {
$("#AR_Register_EMailVerify_Verify_Code_TextBox").focus();
});
break;
default:
AlphaMS.JSToolkit.Dialog.MessageBox(MyResponseObject.ResultMessage);
break;
}
}
}
}, ["Body"]);
},
//提交注册
SubmitRegister: function () {

//检查用户名输入
if ($("#AR_Register_UserName_TextBox").val() == "") {
AlphaMS.JSToolkit.Dialog.MessageBox("请输入用户名", function () {
$("#AR_Register_UserName_TextBox").focus();
});
return;
}

//检查密码输入
if ($("#AR_Register_Password_TextBox").val() == "") {
AlphaMS.JSToolkit.Dialog.MessageBox("请输入密码", function () {
$("#AR_Register_Password_TextBox").focus();
});
return;
}

var PreRegisterString = "您的注册信息如下:</br>";
PreRegisterString = PreRegisterString + "邮件地址:" + $("#AR_Register_EMailVerify_EMailAddress_TextBox").val() + "</br>";
PreRegisterString = PreRegisterString + "用户名:" + $("#AR_Register_UserName_TextBox").val() + "</br>";
PreRegisterString = PreRegisterString + "密码:" + $("#AR_Register_Password_TextBox").val() + "</br>";
PreRegisterString = PreRegisterString + "确认注册吗?";

AlphaMS.JSToolkit.Dialog.MessageBox(PreRegisterString, function () {
//AlphaMS业务逻辑请求
AlphaMS.JSToolkit.NET.BLRequest({
Debug: false,
//业务逻辑方法路由名称
FunctionRouteName: "AlphaMS.Portal.DWeb.Account.NewRegister",
//业务逻辑请求数据
BLRequestObject: {
//请求参数
//用户名
UserName: $("#AR_Register_UserName_TextBox").val(),
//密码
Password: $("#AR_Register_Password_TextBox").val(),
//注册会话编号
RegisterSessionID: PageControl.NewRegisterSessionID
},
//SBS请求返回
BLResponse: {
//请求成功
Success: function (MyResponseObject) {
switch (MyResponseObject.ResultCode) {
case 1:
//注册成功
AlphaMS.JSToolkit.Dialog.MessageBox("注册成功,请前往登录", function () {
AlphaMS.JSToolkit.Action.GoToPage("/Login");
});
break;
case -1:
AlphaMS.JSToolkit.Dialog.MessageBox("注册已经过期,请重新验证邮件地址!", function () {
PageControl.RegisterInit();
});
break;
case -2:
AlphaMS.JSToolkit.Dialog.MessageBox("邮件地址已经存在!", function () {
PageControl.RegisterInit();
});
break;
case -3:
AlphaMS.JSToolkit.Dialog.MessageBox("用户名已经存在,请重新输入!", function () {
$("#AR_Register_UserName_TextBox").focus();
});
break;
default:
AlphaMS.JSToolkit.Dialog.MessageBox(MyResponseObject.ResultMessage);
break;
}
}
}
}, ["Body"]);
}, function () { });

}
}

下面来看一下最终邮件验证的效果

输入邮件地址

 

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

获取验证码

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

收到邮件

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

验证成功,继续填写用户信息

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

注册成功

【初码干货】使用阿里云邮件推送服务架设自己邮件验证与推送体系

四、总结与思考

就此,我们就使用阿里云邮件推送,完成了完整的邮件验证与推送体系的架设(主动推送、数据统计等没有写出来,但是在代码里面有,有需要代码的可以邮件向我索要),一句话总结就是如下:

我想,互联网再怎么发展,QQ号可以没有,微信也可能衰落,但邮件没有的可能性很低,作为一种工作方式和服务方式,在可预见的未来内,邮件体系一定会伴随着信息系统的发展而发展,而从技术的角度出发,对邮件技术和服务的深入研究与思考,一定能够带来更加优秀的软件系统和应用。因此,建议每一个互联网创业者和应用,都能够重视对邮件数据的收集和处理,也在邮件服务上多花点精力和金钱,带给用户更好的体验。


作者:张柔,发布于  博客园  与  初码博客

转载请注明出处,欢迎邮件交流:zhangrou@printhelloworld.com,或者加QQ群:11444444