注册账号后邮箱激活的思路

原创 2012年03月30日 11:39:25

个人觉得,邮箱激活这种做法的意义,是为了验证邮箱的邮箱的有效性,其次防止机器人机械注册非法账号(不是真实存在的人)。


点击“下一步”,发送邮件。把用户提交的表单信息放到XML,等他激活了之后再添加到数据库,然后把XML的相关信息删掉。当然,最好的做法是在直接在数据库里面设置一个状态字段,我们只需要修改一下这两个值就可以了。个人觉得,两个的存储量是一样的,但是操作的话,XML还是麻烦一点,所以推荐使用数据设计状态这种做法。


之前有想过用cookie,用Session来临时存储用户注册信息,但是Cookie有浏览器的差异,换了个浏览器,换个信息就读取不到了,更何况换个电脑呢。Session的生命周期很短,关闭浏览器就结束了。


在发送的邮件里,有激活的链接,比如:http://localhost:2556/WebSite/Register.aspx?Re=YeXJAEYeOXJiJOYeeUQinYeAEJAEHjJHjEs*wenjunli2

这个地址是经过加密的。“*”之前的时间(精确到毫秒),为什么要做这个时间呢,是为了设定在多少时间后失效,失效后把存储的数据删掉(激活失效这个功能)。“*”之后是用户名,其实也应该经过加密,上面没有加密。真正实现激活的是靠这个用户名,如果数据库中存在这个用户名,并且时间没有过期,则激活成功,把数据库用户状态修改。


其实更严谨一点的 做法是对各个参数的值做一个MD5加密,加密后的值(token)作为参数放到URL里面去。用户点击过来的时候,再次验证MD5加密,判断加密后的值是否与token值相等,不相等则用户修改过URL参数。此目的是防止用户修改URl参数对网站做攻击行为。(2017年后再次修改,其实下面的做法过于复杂,但是思路是可以的)


public static string GetStrUserRegist()
        {
            //自己做个格式,比如1对应”XXX1“
            DateTime d1 = DateTime.Now;
            
            List<string> s = new List<string>() { "XJ", "AE", "Ye", "iJ", "Hj", "Ey", "Ys", "Es", "Ts", "eU" };
            string str = d1.ToString("yyyy-MM-dd HH:mm:ss")+d1.Millisecond;//放个时间进去,然后加载的时候再解密
            string NewStr = "";
            //5592012-3-29 17:58:1115
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i].ToString() == "0")
                {
                    NewStr += s[0];
                }
                else if (str[i].ToString() == "1")
                {
                    NewStr += s[1];
                }
                else if (str[i].ToString() == "2")
                {
                    NewStr += s[2];
                }
                else if (str[i].ToString() == "3")
                {
                    NewStr += s[3];
                }
                else if (str[i].ToString() == "4")
                {
                    NewStr += s[4];
                }
                else if (str[i].ToString() == "5")
                {
                    NewStr += s[5];
                }
                else if (str[i].ToString() == "6")
                {
                    NewStr += s[6];
                }
                else if (str[i].ToString() == "7")
                {
                    NewStr += s[7];
                }
                else if (str[i].ToString() == "8")
                {
                    NewStr += s[8];
                }
                else if (str[i].ToString() == "9")
                {
                    NewStr += s[9];
                }
                else if (str[i].ToString() == " ")//当是空的时候
                {
                    NewStr += "Qin";
                }
                else if (str[i].ToString() == ":")
                {
                    NewStr += "J";
                }
                else
                {
                    NewStr += "O";
                }
            }
            return NewStr;
 }



public  class MyService
    {
        // 对称加密算法提供器
        private ICryptoTransform encryptor;     // 加密器对象
        private ICryptoTransform decryptor;     // 解密器对象
        private const int BufferSize = 1024;
        public MyService(string algorithmName, string key)
        {
            SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName);
            provider.Key = Encoding.UTF8.GetBytes(key);
            provider.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            encryptor = provider.CreateEncryptor();
            decryptor = provider.CreateDecryptor();
        }
        public MyService(string key) : this("TripleDES", key) { }
        // 加密算法
        private string Encrypt(string clearText)
        {
            // 创建明文流
            byte[] clearBuffer = Encoding.UTF8.GetBytes(clearText);
            MemoryStream clearStream = new MemoryStream(clearBuffer);
            // 创建空的密文流
            MemoryStream encryptedStream = new MemoryStream();
            CryptoStream cryptoStream =
                new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);
            // 将明文流写入到buffer中
            // 将buffer中的数据写入到cryptoStream中
            int bytesRead = 0;
            byte[] buffer = new byte[BufferSize];
            do
            {
                bytesRead = clearStream.Read(buffer, 0, BufferSize);
                cryptoStream.Write(buffer, 0, bytesRead);
            } while (bytesRead > 0);
            cryptoStream.FlushFinalBlock();
            // 获取加密后的文本
            buffer = encryptedStream.ToArray();
            string encryptedText = Convert.ToBase64String(buffer);
            return encryptedText;
        }
        // 解密算法
        private string Decrypt(string encryptedText)
        {
            byte[] encryptedBuffer = Convert.FromBase64String(encryptedText);
            Stream encryptedStream = new MemoryStream(encryptedBuffer);
            MemoryStream clearStream = new MemoryStream();
            CryptoStream cryptoStream =
                new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
            int bytesRead = 0;
            byte[] buffer = new byte[BufferSize];
            do
            {
                bytesRead = cryptoStream.Read(buffer, 0, BufferSize);
                clearStream.Write(buffer, 0, bytesRead);
            } while (bytesRead > 0);
            buffer = clearStream.GetBuffer();
            string clearText =
                Encoding.UTF8.GetString(buffer, 0, (int)clearStream.Length);
            return clearText;
        }
        /// <summary>
        ///加密
        /// </summary>
        /// <param name="clearText"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Encrypt(string clearText, string key)
        {
            MyService helper = new MyService(key);
            return helper.Encrypt(clearText);
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="encryptedText"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Decrypt(string encryptedText, string key)
        {
            MyService helper = new MyService(key);
            return helper.Decrypt(encryptedText);
        }
}


上面第一个是自己写的一个时间加密规则,第二个是.net的加密规则,其实也可以用MD5,不过我不懂用,也没用过。


/// <summary>
        /// 发送邮件(注册)
        /// </summary>
        /// <param name="name">用户姓名</param>
        /// <param name="userName">用户名</param>
        /// <param name="userPass">密码</param>
        /// <param name="EmailAdd">邮箱地址</param>
        /// <returns></returns>
        public static bool sendEmail(string name, string userName, string userPass, string EmailAdd)
        {
            try
            {
                SmtpClient smtp = new SmtpClient(); //实例化一个SmtpClient
                smtp.DeliveryMethod = SmtpDeliveryMethod.Network; //将smtp的出站方式设为 Network
                smtp.EnableSsl = false;//smtp服务器是否启用SSL加密
                smtp.Host = "smtp.sina.com.cn"; //指定 smtp 服务器地址
                smtp.Port = 25; //指定 smtp 服务器的端口,默认是25,如果采用默认端口,可省去
                //如果你的SMTP服务器不需要身份认证,则使用下面的方式,不过,目前基本没有不需要认证的了
                smtp.UseDefaultCredentials = true; //如果需要认证,则用下面的方式
                smtp.Credentials = new NetworkCredential("qinlin1991@sina.com", "3155446");
                MailMessage mm = new MailMessage(); //实例化一个邮件类
                mm.Priority = MailPriority.High; //邮件的优先级,分为 Low, Normal, High,通常用 Normal即可
                mm.From = new MailAddress("shirilimu@sina.com", "求知科技", Encoding.GetEncoding(936));
                //收件方看到的邮件来源;
                //第一个参数是发信人邮件地址
                //第二参数是发信人显示的名称
                //第三个参数是 第二个参数所使用的编码,如果指定不正确,则对方收到后显示乱码 
                //936是简体中文的codepage值
                //注:上面的邮件来源,一定要和你登录邮箱的帐号一致,否则会认证失败
                mm.ReplyTo = new MailAddress("shirilimu@sina.com", "求知科技", Encoding.GetEncoding(936));
                //ReplyTo 表示对方回复邮件时默认的接收地址,即:你用一个邮箱发信,但却用另一个来收信
                //上面后两个参数的意义, 同 From 的意义
                //mm.CC.Add("a@163.com,b@163.com,c@163.com");
                //邮件的抄送者,支持群发,多个邮件地址之间用 半角逗号分开
                //当然也可以用全地址,如下:
                //mm.CC.Add(new MailAddress(EmailAdd, "覃林", Encoding.GetEncoding(936)));
                //mm.CC.Add(new MailAddress("b@163.com", "抄送者B", Encoding.GetEncoding(936)));
                //mm.CC.Add(new MailAddress("c@163.com", "抄送者C", Encoding.GetEncoding(936)));
                //mm.Bcc.Add("d@163.com,e@163.com");
                //邮件的密送者,支持群发,多个邮件地址之间用半角逗号 分开
                //当然也可以用全地址,如下:
                //mm.CC.Add(new MailAddress("d@163.com", "密送者D", Encoding.GetEncoding(936)));
                //mm.CC.Add(new MailAddress("e@163.com", "密送者E", Encoding.GetEncoding(936)));
                //mm.Sender = new MailAddress("xxx@xxx.com", "邮件发送者", Encoding.GetEncoding(936));
                //可以任意设置,此信息包含在邮件头中,但并不会验证有效性,也不会显示给收件人
                //说实话,我不知道有啥实际作用,大家可不理会,也可不写此项
                //mm.To.Add("g@163.com,h@163.com");
                //邮件的接收者,支持群发,多个地址之间用半角逗号 分开
                //当然也可以用全地址添加
                mm.To.Add(new MailAddress(EmailAdd, name, Encoding.GetEncoding(936)));
                //mm.To.Add(new MailAddress("h@163.com", "接收者h", Encoding.GetEncoding(936)));
                mm.Subject = "考无忧-个人账号信息"; //邮件标题
                mm.SubjectEncoding = Encoding.GetEncoding(936); // 这里非常重要,如果你的邮件标题包含中文,这里一定要指定,否则对方收到的极有可能是乱码。
                // 936是简体中文的pagecode,如果是英文标题,这句可以忽略不用
                mm.IsBodyHtml = true; //邮件正文是否是HTML格式
                mm.BodyEncoding = Encoding.GetEncoding(936); //邮件正文的编码, 设置不正确, 接收者会收到乱码
                mm.Body = "<table style='border:3px solid #D9F4FF;width:658px;' cellspacing='0' cellpadding='0'><tr><td class='style1'><table style='border:1px solid #65C3D6;font-size:12px;' cellspacing='0' cellpadding='0'><tr><td style='width:657px;'><img src='http://www.k51.com.cn/images/logo.jpg' /><br/><b style=' color:#F3750F'>" + name + "</b>:" + "<table cellspacing='0' cellpadding='5' border='0' style='width: 653px; margin-bottom: 0px; margin-top:-10px'><tr><td style='padding:20px 16px;color:#333;'><table cellspacing='0' cellpadding='0' border='0'><tr><td style='padding-left:14px;' class='style3'>您好,感谢您注册考无忧!祝你使用愉快,才识倍增!</td></tr><tr><td style='padding-left:14px;' class='style3'>你的登录名为:<b style='color:#F3750F;'>" + userName + "</b></td></tr> <tr><td style='padding-left:14px;' class='style1'>&nbsp;&nbsp;&nbsp;你的密码为:<b style='color:#F3750F;'>" + userPass + "</b></td></tr>  <tr style=' font-size:15px; font-weight:bold;'><td><a href='"+"http://localhost:2556/WebSite/Register.aspx?Re="+ LoginService.GetStrUserRegist() + " * " + userName +"'>点此链接激活您都账号=></a></td></tr><tr><td>请在40分钟之内激活,逾期无效,抓紧时间哦~</td></tr><tr><td>点击进入考无忧官方网站:<a href='http://www.k51.com.cn'>http://www.k51.com.cn</a></td></tr><tr><td style='color:#999;font-size:12px;display:block;border-top:1px dotted #9F9F9F;padding-top:18px;padding-left:14px;' class='style4'>这只是一封系统自动发出的邮件,请不要直接回复。</td></tr></table></td></tr></table></td></tr></table></td></tr></table>"; //邮件正文
                //mm.Attachments.Add(new Attachment(@"c:\d\1.doc", System.Net.Mime.MediaTypeNames.Application.Rtf)); //添加附件,第二个参数,表示附件的文件类型,可以不用指定
                //可以添加多个附件
                //mm.Attachments.Add(new Attachment(@"d:b.doc"));
                smtp.Send(mm); //发送邮件,如果不返回异常,则大功告成了。
            }
            catch (Exception)
            {
                return false;
            }
            return true;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

点击邮箱链接激活账号

原文地址

账号注册邮箱激活设计

我们在很多网站注册会员时,注册完成后,系统会自动向用户的邮箱发送一封邮件,这封邮件的内容就是一个URL链接,用户需要点击打开这个链接才能激活之前在该网站注册的帐号。激活成功后才能正常使用会员功能。 ...

注册邮箱验证激活账号

注册界面:   http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> http://www.w3.org/1999/xhtml"...

最新整合maven+SSM+Tomcat 实现注册登录

mybatis学习 http://www.mybatis.org/mybatis-3/zh/index.html Spring学习:http://blog.csdn.net/king1425/ar...

SSH之邮箱激活

一、概念了解          要想实现邮箱激活,首先必须明白什么是邮箱激活。大家是否还记得在注册各类账号时,点击注册后往往会提示“是否到邮箱激活?”比如:12306购票软件,QQ,微信等都有这样...

JAVA中的反射机制详解

JAVA反射机制    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称...

使用ssm框架实现用户账户邮箱激活功能(二)

在上一篇中完成了一些准备性的工作,在这一篇中来记录一下框架整合的工作。     首先是准备所需要的jar包,由于没有使用maven,所以所需要的jar包就提前下载好了,其中黄色的jar包是和邮件发送相...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)