WPF帝友借贷系统MV模式开发日志2021/04/04_注册验证&邮箱验证码发送
用户名唯一性验证后,就是验证码验证了
这里验证码使用的是邮箱验证码加上本地验证码的方法
首先,我需要发送一份邮件给注册用户,然后用户根据邮箱接收到的验证码再加上本地的验证码框内的验证码,再填入
那么首先我需要保证用户输入的邮箱地址是正确的,并且唯一,
逻辑需求知道,那么开始工作
首先,依旧是给邮箱输入框绑定逻辑焦点丢失事件LostFocus
///注册页面邮箱检查
UserEmail.LostFocus += UserEmail_LostFocus;
然后写一个邮箱检擦方法EmailFormatCheck
邮箱检查的逻辑是
首先进行邮箱格式的检查,然后再进行邮箱的唯一性检查,
来避免多次查询数据库,减少系统性能
而在网络中,电子邮箱可以自动接收网络任何电子邮箱所发的电子邮件,并能存储规定大小的等多种格式的电子文件。电子邮箱具有单独的网络域名,其电子邮局地址在@后标注,电子邮箱一般格式为:用户名@域名。
—个完整的Internet邮件地址由以下两个部分组成,格式如下:登录名@主机名.域名
中间用—个表示“在”(at)的符号“@”分开,符号的左边是对方的登录名,右边是完整的主机名,它由主机名与域名组成。其中,域名由几部分组成,每一部分称为一个子域(Subdomain),各子域之间用圆点“.”隔开,每个子域都会告诉用户一些有关这台邮件服务器的信息。
从上面的描述就可以看出来,电子邮箱的格式范围很广,唯一比较明显的限制可能就是只有一个"@"符号,但是这并不代表我们能胡来,根据国内一些企业邮箱对于注册邮箱账号的限制,列了几条比较通用的电子邮箱格式限制:
“@”的左边限制:
由a~z的英文字母(不区分大小写)开头
可由英文字母、0~9的数字、点、减号或下划线组成
长度为3~18个字符
不能以点、减号结尾
于是便有了下面的正则表达式
^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$";
将正则表达式设置为一个字段并设置为常量,然后就可以使用了,
private const string RegexEmailVerification = @"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$";
public bool EmailFormatCheck(string email) {
return Regex.IsMatch(email.Trim(), RegexEmailVerification);
}
如上面的EmailFormatCheck方法,该方法需要一个邮箱地址参数,然后该方法会应用上面写的正则表达式字符串并调用正则表达式的匹配,如果匹配合格,则返回一个true
然后邮箱地址格式正确了,就需要进行邮箱地址的唯一性判定了如下
private void UserEmail_LostFocus(object sender, RoutedEventArgs e)
{
if (email.EmailFormatCheck(UserEmail.Text))
{
bool isRepeat = myModel.用户表.Where(m => m.用户邮箱.Equals(UserEmail.Text)).Count() != 0;
TitiRemind(sender, "该邮箱已注册", isRepeat);
VerificationCodeIsGenerated(UserEmail.Text, UserName.Text);
}
else
{
TitiRemind(sender, "邮箱格式有误", true);
}
}
依旧是去数据库内查询用户邮箱地址数据,再调用TitiRemind()方法,这个方法前面说过,这里就不再赘述了
然后,如果邮箱数据只有一条,就调用VerificationCodeIsGenerated方法
public void VerificationCodeIsGenerated(string strUserEmail, string strUserName)
{
int localNumericVerificationCode = new Random(Guid.NewGuid().GetHashCode()).Next(1000, 9999);
int emailVerificationCode = new Random(Guid.NewGuid().GetHashCode()).Next(1000, 9999);
VerificationCode = (localNumericVerificationCode + emailVerificationCode).ToString();
TextBoxVerificationCodeFull.Text = localNumericVerificationCode.ToString();
string messageContent = "《帝友科技》" + emailVerificationCode.ToString() + "注册保护验证码,用于帝友系统用户注册的验证,请勿转发";
email.SendAMessage("jiumeilove@aliyun.com", "帝友科技", "FZY523894.aly", strUserEmail, strUserName, "帝友系统WPF版注册验证码", messageContent);
}
如上,这个方法会调用Random类生成一两个范围为1000至9999的随机数
然后一个随机数转化为字符串传递给页面的验证码显示框
一个数据数调用邮件发送方法发送给用户输入的邮件地址
用户根据这两个验证码进行加法,之后和后台的验证码比对,如果相同,则用户能进行注册,如果不同,则判定为机器人
(其实,这里应该使用服务器来干这种事的,但谁让我没写服务器呢)
那么逻辑知道了,就是代码实现了
实现我需要写一个邮件发送的方法
方法如下
public void SendAMessage(string senderAddress,string senderName,string senderPassword,string recipientAddress, string recipientName, string messageTitle, string messageContent,string strSMTP= "smtp.aliyun.com" )
{
MailAddress from = new MailAddress(senderAddress, senderName); // 邮件的发件人
MailMessage mail = new MailMessage();
// 设置邮件的标题
mail.Subject = messageTitle;
// 设置邮件的发件人
// Pass:如果不想显示自己的邮箱地址,这里可以填符合mail格式的任意名称,真正发mail的用户不在这里设定,这个仅仅只做显示用
mail.From = from;
mail.To.Add(new MailAddress(recipientAddress, recipientName));
// 设置邮件的抄送收件人
//mail.CC.Add(new MailAddress("jiumeilove@aliyun.com", "尊敬的领导"));
// 设置邮件的内容
mail.Body = messageContent;
// 设置邮件的格式
mail.BodyEncoding = System.Text.Encoding.UTF8;
//设置正文是否以html格式
mail.IsBodyHtml = true;
// 设置邮件的发送级别//正常优先级
mail.Priority = MailPriority.Normal;
// 设置邮件的附件,将在客户端选择的附件先上传到服务器保存一个,然后加入到mail中
//string fileName = txtUpFile.PostedFile.FileName.Trim();
//fileName = " D:/UpFile/ " + fileName.Substring(fileName.LastIndexOf(" / ") + 1);
//txtUpFile.PostedFile.SaveAs(fileName); // 将文件保存至服务器
//mail.Attachments.Add(new Attachment(fileName));
//邮件成功送达时通知
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
SmtpClient client = new SmtpClient();
// 设置用于 SMTP 事务的主机的名称,填IP地址也可以了
client.Host = "smtp.aliyun.com";
// 设置用于 SMTP 事务的端口,默认的是 25
client.Port = 25;
client.UseDefaultCredentials = true;
client.EnableSsl = true;
// 这里才是真正的邮箱登陆名和密码,比如我的邮箱地址是 hbgx@hotmail, 我的用户名为 hbgx ,我的密码是 xgbh
client.Credentials = new System.Net.NetworkCredential(senderAddress, senderPassword);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
// 都定义完了,正式发送;
client.Send(mail);
}
如上代码,当用户当邮件发送之后用户会收到一个验证码并且,本程序所使用的邮箱地址也回收到一份备份邮件
用户根据收到的邮件和本地验证码框所显示的验证码两两相加,得出真正的验证码.然后使用验证码验证码注册
当用户输入了验证码之后,点击注册按钮
private void ButtonUserEnroll_Click(object sender, RoutedEventArgs e)
{
string verificationCode = TextBoxVerificationCode.Text;
if (!verificationCode.Equals(this.VerificationCode))
{
MessageBox.Show("验证码输入错误,请重新输入");
TextBoxVerificationCode.Text = "";
return;
}
Model.用户表 yongHu = new Model.用户表
{
用户头像 = "shandianxiaofeixia.png",
用户昵称 = UserName.Text,
用户密码 = UserPassword.Password,
用户邮箱 = UserEmail.Text,
用户性别ID = ((dynamic)UserSex.SelectedItem).id,
注册时间 = DateTime.Now
};
myModel.用户表.Add(yongHu);
if (myModel.SaveChanges() != 1)
{
MessageBox.Show("用户新增失败");
return;
}
Model.会员表 huiYuan = new Model.会员表
{
用户ID = yongHu.用户ID,
会员等级ID = 1,
会员编号 = "HY" + DateTime.Now.ToString("yyyyMMddHHmmss"),
会员信用积分 = 0,
会员信用等级ID = 0
};
myModel.会员表.Add(huiYuan);
if (myModel.SaveChanges() != 1)
{
MessageBox.Show("用户新增失败");
return;
}
if (MessageBox.Show("用户新增成功,自动成为免费会员,要用此账户直接登入吗?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Information).ToString() == "Yes")
{
UserLogin(yongHu, true, false);
}
就来到了上面这个方法,上面这个方法会去比对用户输入的方法是否正确,然后,如果正确的话,就新增用户数据,
并自动将用户注册成为免费会员
再然后询问用户,是否直接登入,如果用户选是,就直接使用本账户登入,否则不登入