注册邮箱验证激活技术

一.先说思路

//1.数据库加三个字段,state:(0:未激活,1:激活成功),ActiCode:(放激活码),token_exptime(过期时间,用来验证激活邮件是否过期)

//2.用户填写资料,点击注册,插入数据成功,state字段默认是0,同时生成一个ActiCode(用传过来的邮箱、密码、和当前时间加密形成)也存入数据库

//3.发送邮件。。。提示用户登录邮箱激活。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码)

//4.用户登录邮箱点击链接,来到处理激活的业务逻辑页面或Servlet,得到URL中两个参数,以这两个参数为条件查询数据库里的数据,如果有,取当前时间和之前存入数据库的过期时间作比较,看是否过期,过期,删除数据库中该条记录,并转到失败页面,没过期,查看链接传过来的激活码与数据库字段激活码是否一致,不一致,同样删除数据库中该条记录,并跳转到激活失败界面,一致,则将字段state为1,激活成功,转到激活成功页。。。

 

二、具体实现代码

      1.首先,准备一个简单的测试页面

<body>  
    <div id="main" style="margin:0 auto;width:500px;">  
    <form id="reg" action="user.action?op=reg" method="post">  
        <p>  
            E-mail:<input type="text" class="input" name="email" id="email">  
        </p>  
        <p>  
            密 码:<input type="password" class="input" name="pwd" id="pwd">  
        </p>  
        <p>  
            <input type="submit" class="btn" value="提交注册" >  
        </p>  
    </form>  
    </div>  
      
</body>  

 2.点击提交注册,来到user.action?op=reg,注意带的参数op指我要做的操作,用于后面的Servlet做判断该做什么操作,下面的代码完成了形成激活码、过期时间等表示当前注册用户的状态的信息存入数据库并发送邮件的过程。(邮件内容自定义,可以忽略我的)

 

  1 package com.nh.web.servlets;  
  2   
  3 import java.io.IOException;  
  4 import java.io.PrintWriter;  
  5 import java.sql.SQLException;  
  6 import java.text.SimpleDateFormat;  
  7 import java.util.ArrayList;  
  8 import java.util.Calendar;  
  9 import java.util.Date;  
 10 import java.util.List;  
 11 import java.util.UUID;  
 12   
 13 import javax.naming.NamingException;  
 14 import javax.servlet.ServletException;  
 15 import javax.servlet.http.HttpServlet;  
 16 import javax.servlet.http.HttpServletRequest;  
 17 import javax.servlet.http.HttpServletResponse;  
 18   
 19 import com.nh.dao.DBHelper;  
 20 import com.nh.utils.Encrypt;  
 21 import com.nh.utils.SendEmail;  
 22   
 23 public class UserServlet extends CommonServlet {  
 24   
 25     public void doPost(HttpServletRequest request, HttpServletResponse response)  
 26             throws ServletException, IOException {  
 27         // 取出op  
 28         String op = request.getParameter("op");  
 29         // 判断op是什么,调用不同的方法做处理  
 30         try {  
 31             if (op != null && !"".equals(op)) {  
 32                 if ("reg".equals(op)) {  
 33                     regOP(request, response);  
 34                 }  
 35             } else {  
 36   
 37             }  
 38         } catch (Exception e) {  
 39             e.printStackTrace();  
 40             response.sendRedirect("common/500.jsp");  
 41         }  
 42     }  
 43   
 44     private void regOP(HttpServletRequest request, HttpServletResponse response) throws IOException, SQLException, NamingException {  
 45 //      1.数据库加两个字,state字段(0:未激活,1:激活成功),ActiCode:(放激活码)  
 46 //      2.用户填写资料,插入数据成功,state字段默认是0,同时生成一个ActiCode也存入数据库  
 47 //      3.提示用户激活。。。发送邮件。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码)  
 48 //      4.用户点击链接,回到激活成功页。。。激活成功页的Load事件,得到两个参数,以这两个参数为条件查询数据库里的数据,如果有,修改字段state为1,反之。。提示激活失败,重新激活。。   
 49           
 50         String email=request.getParameter("email");   
 51         String pwd=Encrypt.md5(request.getParameter("pwd"));  
 52         Calendar c = Calendar.getInstance();  
 53         //现在的时间(单位:毫秒)  
 54         //TODO:时间换算问题,如何处理int和long之间的关系  
 55         long time = c.getTimeInMillis();  
 56   
 57         //创建激活码  
 58         String token=Encrypt.md5(email+pwd+time);  
 59         //过期时间为24小时后  
 60 //      int token_exptime=(int)(time+1000*60*60*24);  
 61         String token_exptime=(time+1000*20)+"";    //这里测试是用的20秒  
 62           
 63         String id=UUID.randomUUID().toString();  
 64         String sql="insert into tb_user(id,username,pwd,token,token_exptime,regtime,status) values (?,?,?,?,?,sysdate,0)";  
 65           
 66         List<Object> params=new ArrayList<Object>();  
 67         params.add(id);  
 68         params.add(email);  
 69         params.add(pwd);  
 70         params.add(token);  
 71         params.add(token_exptime);  
 72           
 73         DBHelper db=new DBHelper();  
 74         int r=db.doUpdate(sql, params); //保存注册信息  
 75           
 76         if( r>0 ){  
 77             //发送邮件  
 78             ///邮件的内容  
 79             SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
 80               
 81             StringBuffer sb=new StringBuffer("<div style=\"width:660px;overflow:hidden;border-bottom:1px solid #bdbdbe;\"><div style=\"height:52px;overflow:hidden;border:1px solid #464c51;background:#353b3f url(http://www.lofter.com/rsc/img/email/hdbg.png);\"><a href=\"http://www.lofter.com?mail=qbclickbynoticemail_20120626_01\" target=\"_blank\" style=\"display:block;width:144px;height:34px;margin:10px 0 0 20px;overflow:hidden;text-indent:-2000px;background:url(http://www.lofter.com/rsc/img/email/logo.png) no-repeat;\">LOFTER</a></div>"+"<div style=\"padding:24px 20px;\">您好,"+email+"<br/><br/>LOFTER是一款\"专注兴趣、分享创作\"的轻博客产品,旨在为\"热爱记录生活、追求时尚品质、崇尚自由空间\"的你,打造一个全新而定展示平台!<br/><br/>请点击下面链接激活账号,24小时生效,否则重新注册账号,链接只能使用一次,请尽快激活!</br>");  
 82             sb.append("<a href=\"http://localhost:8080/mailtest/emailcheck.action?op=activate&id=");  
 83             sb.append(id);  
 84             sb.append("&token=");  
 85             sb.append(token);  
 86             sb.append("\">http://localhost:8080/mailtest/emailcheck.action?op=activate&id=");  
 87             sb.append(id);  
 88             sb.append("&token=");  
 89             sb.append(token);  
 90             sb.append("</a>"+"<br/>如果以上链接无法点击,请把上面网页地址复制到浏览器地址栏中打开<br/><br/><br/>LOFTER,专注兴趣,分享创作<br/>"+sdf.format(new Date())+ "</div></div>" );  
 91   
 92             //发送邮件  
 93             SendEmail.send(email, sb.toString());  
 94         }  
 95           
 96         response.sendRedirect("doEmail.action?op=emaillogin&email="+email+"&pwd="+pwd);  
 97           
 98     }  
 99   
100 }  

发送邮件的代码,这里需要导入javax.mail的包,即mail.jar,如果发件人邮箱是QQ邮箱还要去QQ邮箱开启smtp和其他两个协议,我这里用的163邮箱就不需要设置

 1 package com.nh.utils;  
 2   
 3 import java.util.Date;  
 4 import java.util.Properties;  
 5   
 6 import javax.mail.Authenticator;  
 7 import javax.mail.Message;  
 8 import javax.mail.MessagingException;  
 9 import javax.mail.PasswordAuthentication;  
10 import javax.mail.Session;  
11 import javax.mail.Transport;  
12 import javax.mail.internet.InternetAddress;  
13 import javax.mail.internet.MimeMessage;  
14   
15   
16 /** 
17  * 
18  * @author Qixuan.Chen 
19  */  
20 public class SendEmail {  
21   
22     public static final String HOST = "smtp.163.com";  
23 //    public static final String PROTOCOL = "smtp";    
24 //    public static final int PORT = 25;  
25   
26     public static final String FROM = "xxxx@163.com";//发件人的email  
27     public static final String PWD = "xxxx";//发件人密码  
28       
29   
30     /** 
31      * 获取Session 
32      * @return 
33      */  
34     private static Session getSession() {  
35         Properties props = new Properties();  
36         props.put("mail.smtp.host", HOST);//设置服务器地址  
37 //        props.put("mail.store.protocol" , PROTOCOL);//设置协议  
38 //        props.put("mail.smtp.port", PORT);//设置端口  
39         props.put("mail.smtp.auth" , "true");  
40   
41         Authenticator authenticator = new Authenticator() {  
42   
43             @Override  
44             protected PasswordAuthentication getPasswordAuthentication() {  
45                 return new PasswordAuthentication(FROM, PWD);  
46             }  
47   
48         };  
49         Session session = Session.getDefaultInstance(props , authenticator);  
50   
51         return session;  
52     }  
53   
54     public static void send(String toEmail , String content) {  
55         Session session = getSession();  
56         try {  
57           //  System.out.println("--send--"+content);  
58             // Instantiate a message  
59             Message msg = new MimeMessage(session);  
60   
61             //Set message attributes  
62             msg.setFrom(new InternetAddress(FROM));  
63             InternetAddress[] address = {new InternetAddress(toEmail)};  
64             msg.setRecipients(Message.RecipientType.TO, address);  
65             msg.setSubject("账号激活邮件");  
66             msg.setSentDate(new Date());  
67             msg.setContent(content , "text/html;charset=utf-8");  
68   
69             //Send the message  
70             Transport.send(msg);  
71         }  
72         catch (MessagingException mex) {  
73             mex.printStackTrace();  
74         }  
75     }  
76   
77 }  

这是收到的激活邮件

根据用户所填邮箱跳转相应邮箱登录地址的代码

 1 package com.nh.web.servlets;  
 2   
 3 import java.io.IOException;  
 4 import java.io.PrintWriter;  
 5   
 6 import javax.servlet.ServletException;  
 7 import javax.servlet.http.HttpServlet;  
 8 import javax.servlet.http.HttpServletRequest;  
 9 import javax.servlet.http.HttpServletResponse;  
10   
11 public class DoEmailLoginServlet extends CommonServlet {  
12   
13     public void doPost(HttpServletRequest request, HttpServletResponse response)  
14             throws ServletException, IOException {  
15         String op = request.getParameter("op");  
16         // 判断op是什么,调用不同的方法做处理  
17         try {  
18             if (op != null && !"".equals(op)) {  
19                 if ("emaillogin".equals(op)) {  
20                     emailloginOP(request, response);  
21                 }  
22             } else {  
23   
24             }  
25         } catch (Exception e) {  
26             e.printStackTrace();  
27             response.sendRedirect("common/500.jsp");  
28         }  
29     }  
30   
31     private void emailloginOP(HttpServletRequest request,  
32             HttpServletResponse response) throws IOException {  
33         //判断用户邮箱是什么,跳到指定邮箱登陆界面  
34         String email=request.getParameter("email"); //572480349@qq.com  
35         String pwd=request.getParameter("pwd");  
36         String addrstr=email.split("@")[1]; //qq.com  
37           
38         if( "qq.com".equals(addrstr)){  
39             addrstr="https://mail.qq.com";  
40         }else if( "163.com".equals(addrstr)){  
41             addrstr="http://mail.163.com/";  
42         }else if( "126.com".equals(addrstr)){  
43             addrstr="http://www.126.com/";  
44         }else if( "sina.com".equals(addrstr)){  
45             addrstr="http://mail.sina.com.cn/";  
46         }else if( "hotmail.com".equals(addrstr)){  
47             addrstr="https://login.live.com";  
48         }  
49           
50         response.sendRedirect("emailaction.jsp?email="+email+"&pwd="+pwd+"&addrstr="+addrstr);  
51     }  
52   
53 }  

具体页面我就不一一给了,直接上激活验证代码吧

  1 package com.nh.web.servlets;  
  2   
  3 import java.io.IOException;  
  4 import java.io.PrintWriter;  
  5 import java.lang.reflect.InvocationTargetException;  
  6 import java.sql.SQLException;  
  7 import java.util.ArrayList;  
  8 import java.util.Calendar;  
  9 import java.util.List;  
 10   
 11 import javax.naming.NamingException;  
 12 import javax.servlet.ServletException;  
 13 import javax.servlet.http.HttpServlet;  
 14 import javax.servlet.http.HttpServletRequest;  
 15 import javax.servlet.http.HttpServletResponse;  
 16   
 17 import com.lofter.bean.User;  
 18 import com.nh.dao.DBHelper;  
 19 import com.nh.utils.DataExistAlreadyException;  
 20   
 21 public class EmailActivateCheckServlet extends CommonServlet {  
 22   
 23     public void doPost(HttpServletRequest request, HttpServletResponse response)  
 24             throws ServletException, IOException {  
 25         // 取出op  
 26                 String op = request.getParameter("op");  
 27                 // 判断op是什么,调用不同的方法做处理  
 28                 try {  
 29                     if (op != null && !"".equals(op)) {  
 30                         if( "activate".equals(op)){  
 31                             activateOP(request,response);  
 32                         }  
 33                     } else {  
 34   
 35                     }  
 36                 } catch (Exception e) {  
 37                     e.printStackTrace();  
 38                     response.sendRedirect("common/500.jsp");  
 39                 }  
 40     }  
 41   
 42     private void activateOP(HttpServletRequest request,  
 43             HttpServletResponse response) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, Exception {  
 44         //获取参数token的值,即激活识别码。  
 45         //将它与数据表中的用户信息进行查询对比,如果有相应的数据集,判断是否过期,如果在有效期内则将对应的用户表中字段status设置1,即已激活,这样就完成了激活功能。  
 46           
 47         String id=request.getParameter("id");  
 48         String token=request.getParameter("token");  
 49         Calendar c = Calendar.getInstance();  
 50         //现在的时间(单位:毫秒)  
 51         long curtime = c.getTimeInMillis();  
 52           
 53         String sql="select id,token_exptime,token,username,pwd from tb_user where status=0 and  token=?";  
 54         List<Object> params=new ArrayList<Object>();  
 55         params.add( token );  
 56           
 57         DBHelper db=new DBHelper();  
 58         User u=db.findSingleObject(User.class, sql, params);  
 59         String email=u.getUsername();  
 60         String pwd=u.getPwd();  
 61         if( u!=null ){  
 62             long token_exptime=Long.parseLong(u.getToken_exptime());  
 63             if( curtime>token_exptime ){  
 64                 //激活码过期,先删除该用户记录,然后重新发送邮件  
 65                 sql="delete from tb_user where id='"+u.getId()+"'";  
 66                 db.doUpdate(sql, null);  
 67                 response.sendRedirect("actionfailer.jsp?email="+email+"&pwd="+pwd);  
 68             //   throw new DataExistAlreadyException("激活码已过期!");  
 69                  return;  
 70             }else{  
 71                 //验证激活码是否正确  
 72                 if( token.equals(u.getToken())){  
 73                     //激活成功, //并更新用户的激活状态,为已激活   
 74                     sql="update tb_user set status=1 where id='"+u.getId()+"'";  
 75                     db.doUpdate(sql, null);  
 76                     response.sendRedirect("actionsuccess.jsp");  
 77                 }else{  
 78                     sql="delete from tb_user where id='"+u.getId()+"'";  
 79                     db.doUpdate(sql, null);  
 80                     response.sendRedirect("actionfailer.jsp?email="+email+"&pwd="+pwd);  
 81                     return;  
 82             //       throw new DataExistAlreadyException("激活码不正确");    
 83                 }  
 84             }  
 85         }   
 86           
 87     }  
 88   
 89 }  
 90   
 91   
 92   
 93 package com.nh.web.servlets;  
 94   
 95 import java.io.IOException;  
 96 import java.io.PrintWriter;  
 97   
 98 import javax.servlet.ServletContext;  
 99 import javax.servlet.ServletException;  
100 import javax.servlet.http.HttpServlet;  
101 import javax.servlet.http.HttpServletRequest;  
102 import javax.servlet.http.HttpServletResponse;  
103 import javax.servlet.http.HttpSession;  
104   
105   
106 public abstract class CommonServlet extends HttpServlet {  
107     private static final long serialVersionUID = 3893961453320250657L;  
108   
109     private String saveFilePath="";  
110     protected String basePath="";  
111       
112       
113     @Override  
114     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
115             throws ServletException, IOException {  
116         doPost(req,resp);  
117     }  
118   
119     @Override  
120     protected void service(HttpServletRequest req, HttpServletResponse resp)  
121             throws ServletException, IOException {  
122           
123         saveFilePath=req.getRealPath("/");  
124         HttpSession session=req.getSession();  
125         ServletContext application=session.getServletContext();  
126         if( application.getAttribute("basePath")!=null ){  
127             basePath=(String) application.getAttribute("basePath");  
128         }  
129           
130         super.service(req, resp);  
131     }  
132       
133       
134 }  
135   
136   
137 package com.lofter.bean;  
138   
139 import java.io.Serializable;  
140 import java.util.Date;  
141   
142 public class User implements Serializable {  
143   
144     private static final long serialVersionUID = -1989259749641485708L;  
145   
146     private String id;  
147     private String username; // --账户  
148     private String pwd; // --密码  
149     private String nickname; // --名称  
150     private String autograph; // --个人签名  
151     private String head; // --头像  
152     private Date regtime; // --注册时间  
153   
154     private String token; // --账号激活码  
155     private String token_exptime; // --激活码有效期  
156     private Integer status; // --激活状态 ,0-未激活,1-已激活  
157   
158     public User() {  
159         super();  
160     }  
161   
162       
163       
164     public User(String id, String username, String pwd, String nickname,  
165             String autograph, String head, Date regtime, String token,  
166             String token_exptime, Integer status) {  
167         super();  
168         this.id = id;  
169         this.username = username;  
170         this.pwd = pwd;  
171         this.nickname = nickname;  
172         this.autograph = autograph;  
173         this.head = head;  
174         this.regtime = regtime;  
175         this.token = token;  
176         this.token_exptime = token_exptime;  
177         this.status = status;  
178     }  
179   
180   
181   
182     public String getId() {  
183         return id;  
184     }  
185   
186     public void setId(String id) {  
187         this.id = id;  
188     }  
189   
190     public String getUsername() {  
191         return username;  
192     }  
193   
194     public void setUsername(String username) {  
195         this.username = username;  
196     }  
197   
198     public String getPwd() {  
199         return pwd;  
200     }  
201   
202     public void setPwd(String pwd) {  
203         this.pwd = pwd;  
204     }  
205   
206     public String getNickname() {  
207         return nickname;  
208     }  
209   
210     public void setNickname(String nickname) {  
211         this.nickname = nickname;  
212     }  
213   
214     public String getAutograph() {  
215         return autograph;  
216     }  
217   
218     public void setAutograph(String autograph) {  
219         this.autograph = autograph;  
220     }  
221   
222     public String getHead() {  
223         return head;  
224     }  
225   
226     public void setHead(String head) {  
227         this.head = head;  
228     }  
229   
230     public Date getRegtime() {  
231         return regtime;  
232     }  
233   
234     public void setRegtime(Date regtime) {  
235         this.regtime = regtime;  
236     }  
237   
238     public static long getSerialversionuid() {  
239         return serialVersionUID;  
240     }  
241   
242     public String getToken() {  
243         return token;  
244     }  
245   
246     public void setToken(String token) {  
247         this.token = token;  
248     }  
249   
250     public String  getToken_exptime() {  
251         return token_exptime;  
252     }  
253   
254     public void setToken_exptime(String token_exptime) {  
255         this.token_exptime = token_exptime;  
256     }  
257   
258     public Integer getStatus() {  
259         return status;  
260     }  
261   
262     public void setStatus(Integer status) {  
263         this.status = status;  
264     }  
265   
266       
267   
268 }  

 

posted @ 2017-11-09 14:14  gzcblogs  阅读(1411)  评论(0编辑  收藏  举报