专栏首页Don的成长史C#通过邮箱验证来找回密码

C#通过邮箱验证来找回密码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42449444/article/details/90722070

写在前面:

嘤嘤嘤 开头嘤嘤嘤,先扯一哈卵谈?,然后再聊代码修福报。大家都知道忘记密码一直是一个让人头大的问题,比如我这鱼的记忆就忘记了Ubuntu里面的MySql密码 然后直接GG...只能删库跑路啦 我没了 我人直接没啦。这是双系统里面的Ubuntu,不是虚拟机里的Ubuntu,有图有真相.....忘记密码的后果是很严重的。

正是因为有极少部分像我一样的、会忘记密码的沙雕存在,所以找回密码功能是非常重要的。找回密码功能简单来说就是俩个步骤:①输入账号并通过验证,证明这个号是你的;②输入新密码,MD5加密保存到数据库的用户表中。(关于MD5加密存储,前段时间写过一篇博文 传送门:C#操作Sql Server数据库以及MD5加密存储)。现在的验证方式有很多种:通过邮箱进行验证、通过手机号进行短信验证、通过密保问题进行验证...等等。我考虑到运营商需要收取一毛钱一条的短信费,于是手机号验证直接被我pass掉了(此处手动滑稽并流下穷人的泪水)。然后通过密保问题来进行很简单实现的,我记得早期QQ就有这个密保验证找回密码的功能。当时QQ要求填写3个密保问题,比如:你的小学班主任是?你的学号是?.....个人不是很喜欢密保问题验证找回密码,于是我在数据库大作业中选择的找回密码方式是邮箱认证。好了 原谅我是个话痨,终于说到这篇博文的正题啦——C#如何通过邮箱认证来找回密码。(QQ邮箱的小弹窗真好!点击文本链接还可以跳转到网页)。

获取QQ邮箱授权码:

在QQ邮箱的邮箱设置中,进入账户页面,开启QQ邮箱的一系列服务?然后验证密保即可获取当前账号的QQ邮箱授权码。什么是授权码,它又是如何设置的?咱也不知道咱也不敢问(手动滑稽.jpg 紫色字体是传送门 点击跳转)。

授权码其实就是一个QQ邮箱推出的、长度为16位的、用于登录第三方客户端的专用密码。

————————————————2019.06.20更新—————————————————

需要注意一点:QQ邮箱的授权码是具有时效性的,一段时间后授权码会失效而导致邮箱验证码发送失败。

这种情况很好解决的,只需要在QQ邮箱中重新获取一个新的授权码即可,为了方便更新授权码,我把授权码写成了全局变量。

这样只需把之前的源代码中的发件人邮箱用Program.QQemail代替,授权码用Program.AuthorizationCode代替即可。

————————————————————————————————————————

验证码的生成:

验证码的生成,其实就是伪随机字符串的生成。这部分在前面的博文C#生成图形验证码中已经提到过了。我是通过无脑for循环+Random随机选择字符来实现的.......?

先把验证码中包含的所有元素(大小写字母和数字)放入一个string型的字符串list中,然后调用Random()随机生成一个下标,通过这个下标来获取list中对应的字符,for循环length次后,就能得到一个长度为length的伪随机验证码。是不是很简单很low呀??我直接把这段代码写在了项目的静态类Program中,这样的话,所有窗体都可以通过调用静态方法Program.CreateRandomCode(length)来生成一个包含大小写字母和数字的、长度位length的伪随机验证码。

public static string CreateRandomCode(int length)  //生成由数字和大小写字母组成的验证码
{
    string list = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";  
    //list中存放着验证码的元素
    Random random = new Random();
    string code = "";   //验证码
    for (int i = 0; i < length; i++)   //循环6次得到一个伪随机的六位数验证码
    {
        code += list[random.Next(0, list.Length - 1)];
    }
    return code;
}

C#发送邮件:

嘤嘤嘤,这部分需要先引进俩个命名空间。

using System.Net;
using System.Net.Mail;

接着实例化邮件类MailMessage,然后就像很简单了呀。像正常地写邮件一样:输入收件人邮箱地址、邮件标题、邮件内容等等。最后输入发件人邮箱和邮箱授权码验证你的身份就发送成功了。

MailMessage mail = new MailMessage();  //实例化一个邮件类
mail.From = new MailAddress("(发件人邮箱地址)");   //发件人邮箱地址
mail.To.Add(new MailAddress("(收件人邮箱地址)"));    //收件人邮箱地址
mail.Subject = "(邮件标题)";    //邮件标题
mail.Body = "(邮件内容)";  //邮件内容          
SmtpClient client = new SmtpClient("smtp.qq.com");   //实例化一个SmtpClient类
client.EnableSsl = true;    //使用安全加密连接
client.Credentials = new NetworkCredential("(发件人邮箱)", "(邮箱授权码)");//验证发件人身份(发件人邮箱,邮箱授权码);
client.Send(mail);  //发送邮件
MessageBox.Show("发送成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

不要问我是怎么晓得的,问就是我像蔡徐坤一样会ctrl。虽然我写代码的样子菜得像蔡徐坤,但是我会ctrl啊。写代码的样子菜得像蔡徐坤真的一点不要紧,最重要的是要像蔡徐坤一样会ctrl,这里的ctrl不是指像坤坤一样喜欢唱跳rap篮球,而是说要会用多用ctrl+鼠标左键。碰到不懂的函数或类就直接Ctrl+鼠标左键点击它查看它的定义。

比如对着MailMessage按下ctrl+鼠标左键点击后,就能查看它的定义,如图:

邮箱验证的时间控制:

根据常识我们可以知道,邮箱验证的时间是需要控制的,比如:①发送邮件验证码的一定时间内不能再次发送(我设定的是1分钟);②邮件验证码具有时效性,超过一定的时间验证码就会失效(我设定的是5分钟)。我先定义了全局变量:俩个计时器cnt1、cnt2和一个邮箱验证码code。然后用到了俩个Timer控件,一个用于控制多次发送验证码的时间间隔,一个用来记录验证码的有效期限。"Talk is cheap, show me the code." (注释已经写得很详细啦)

private void Button_Click(object sender, EventArgs e)   //发送邮箱验证码
{
    string userid = textBox1.Text.Trim();   //账号
    string email = textBox2.Text.Trim();    //邮箱
    if (!String.IsNullOrEmpty(userid)&&!String.IsNullOrEmpty(email))  //账号、邮箱非空
    {
        SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=Library;User ID=sa;Password=sql123");
        connection.Open();
        SqlCommand command = new SqlCommand("SELECT username,email FROM login_table WHERE username='" + userid + "' AND email='" + email + "'", connection);
        SqlDataReader data = command.ExecuteReader();
        if (data.HasRows)   //若输入的电子邮箱是账号注册时填写的邮箱
        {
            try
            {
                MailMessage mail = new MailMessage();  //实例化一个发送邮件类
                mail.From = new MailAddress("tanyaodan@qq.com");   //发件人邮箱地址
                mail.To.Add(new MailAddress(email));    //收件人邮箱地址
                mail.Subject = "【HBU图书管理系统】找回密码";    //邮件标题
                code = Program.CreateRandomCode(6);   //生成伪随机的6位数验证码
                mail.Body = "验证码是: " + code + ",请在5分钟内进行验证。验证码提供给他人可能导致账号被盗,请勿泄露,谨防被骗。系统邮件请勿回复。";  //邮件内容          
                SmtpClient client = new SmtpClient("smtp.qq.com");   //实例化一个SmtpClient类。
                client.EnableSsl = true;    //使用安全加密连接
                client.Credentials = new NetworkCredential("tanyaodan@qq.com", "(16位授权码不能泄露)");//验证发件人身份(发件人的邮箱,邮箱里的生成授权码);        
                client.Send(mail);
                //计时器初始化
                cnt1 = 60;
                cnt2 = 300;
                timer1.Enabled = true;   //time1用来记录1分钟
                timer2.Enabled = true;   //time2用来记录5分钟
                button.Enabled = false;  //发送按钮不可点击
                //MessageBox.Show("发送成功!");
            }
            catch
            {
               MessageBox.Show("发送失败!\n请检查邮箱是否输入有误。", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        else
        {
            MessageBox.Show("该邮箱不是账号绑定的邮箱。", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    else
    {
        MessageBox.Show("请将账号和邮箱填写完整!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    }
}

private void Timer1_Tick(object sender, EventArgs e)    //发送完邮件,需要60秒后才能再次发送邮件
{
    if (cnt1 > 0)
    {
        cnt1--;
        button.Text = "发送(" + cnt1 + ")";
    }
    else
    {
        timer1.Enabled = false;
        button.Enabled = true;
        button.Text = "发送";
    }
}

private void Timer2_Tick(object sender, EventArgs e)    //验证码5分钟内有效,但是如果有新的验证码出现,旧验证码就会GG
{
    if (cnt2 == 0)
    {
        timer2.Enabled = false;
        code = Program.CreateRandomCode(6);    //旧的验证码过期,生成一个新的验证码
    }
}

关于账号绑定邮箱:

这部分我是在用户注册的时候实现的,将用户注册的所有信息都保持到sql server数据库中的login_table表中。在找回密码时,只需要连接到sql server通过SELECT语句进行查询即可,只有当输入的账号和邮箱是绑定好的才能发送邮件验证码进行邮箱验证。这部分很简单实现的,在上面的那个代码块里已经写啦,看下效果图吧(原谅我的找回密码界面很丑?)。

验证码正误判断:

验证码的判断是忽略字母大小写的,这里我把文本框textBox中输入的内容和邮箱验证码都通过ToLower()来转换成小写字母再进行比对。

if (textBox.Text.ToLower() != code.ToLower())   //若验证码输入错误
{
    MessageBox.Show("您输入的验证码有误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else   //验证成功
{
    MessageBox.Show("验证成功!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
}

好好coding,天天向上!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C#生成图形验证码

    我弄的这个图形验证码是通过伪随机验证码+label控件+背景图来实现的,我觉得我这个图形验证码写得比较low,用代码实现起来也特别简单。

    喜欢ctrl的cxk
  • 判断题最多获得多少分

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • 【PAT乙级】D进制的A + B

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • 安全漏洞公告

    1 Apache Tomcat XML外部实体信息泄露漏洞 Apache Tomcat XML外部实体信息泄露漏洞发布时间:2014-02-26漏洞编号:BUG...

    安恒信息
  • Java中高级面试题部分答案解析(1)

    这里选几道常见的做一些答案解析,参考网络上优质的博客加一些理解。当然不一定全部正确,有一些是没有固定答案的,如果发现有错的或者更适合的答案欢迎留言矫正,就这样。

    java思维导图
  • Java中高级面试题(1)

    1、ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。

    芋道源码
  • Spring和性——数据的类型转换

    在字符串到实体转换一文中介绍了Spring核心框架中使用PropertyEditor将任何字符串转换为数字、实体的方法。除了字符串到实体,Spring还提供了更...

    随风溜达的向日葵
  • HackerOne平台2016年最具竞争力的漏洞悬赏项目

    互联网充斥着漏洞,这是不足为奇的事。从程序员开始写代码起,他们就必定会犯错。而只要他们犯错,犯罪分子、政府、黑客分子就都能对这些漏洞无所不用其极。 谷歌、Fac...

    FB客服
  • Android RxJava 实战讲解:优雅实现 网络请求轮询

    注:关于 Rxjava中的延时创建操作符interval() 和 intervalRange()的使用请看文章Android RxJava:最基础的操作符详解 ...

    Carson.Ho
  • 2018-09-05 log不输出堆栈信息,写了个测试

    Albert陈凯

扫码关注云+社区

领取腾讯云代金券