Java实现注册邮箱激活账户实例代码
在网站注册时一般都会要验证注册用户身份的合法性,通常的做法是提供手机号验证或者邮箱验证。
手机验证:填写手机号码,点击发送验证码,接收后填写验证码比对,无误后注册成功。
邮箱验证:注册时填写邮箱账号,点击注册,网站邮箱会给该邮箱发送一封激活邮件,用户点击后激活该账号。
这里通过实例来介绍一下邮箱验证的实现过程,例子可以运行,暂时没有发现什么问题,不过也可能有不安全的地方,欢迎大家指正。
实现思路
注册时填写邮箱,点击注册时网站系统邮箱发送激活验证链接到此邮箱,用户来激活账户
点击注册,系统邮箱会发送一封激活邮件到你填写的邮箱账号中
在没有进行激活操作前,设定某个字段状态是0,表示此账号未激活,不可以使用或者某些功能受限
激活操作之后,将activated字段更新为1,这样就完成了激活操作
那么这里还有一个codeUrl字段,他的作用是存入一个唯一标识的随机码,这个随机码由用户名和UUID唯一标识的随机数组成,这样做的目的是防止用户使用不存在的邮箱又修改链接中的参数来激活账户,将链接中的随机码和数据库中的比对,来达到相对安全的激活。
下面是具体的代码
首先是注册的servlet,这里主要测试激活账号的功能,注册代码有点low,不安全,将就看一下
package org.amuxia.emailtest.servlet; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.amuxia.emailtest.pojo.User; import org.amuxia.emailtest.utils.EmailUtils; import org.amuxia.emailtest.utils.MyJDBC; /** * @author amuxia * 2017年7月24日 */ @WebServlet("/RegistServlet") public class RegistServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String email = request.getParameter("email"); String codeUrl = UUID.randomUUID().toString(); User user = new User(); user.setUsername(username); user.setPassword(password); user.setEmail(email); user.setActivated(false); //刚注册默认是没有激活状态 String SQL = "insert into tb_user(username,password,email,activated,codeUrl) value (?,?,?,?,?) "; MyJDBC.insert(SQL, false, username,password,email,0,codeUrl);//注册信息插入数据库 String querySQL = "select * from tb_user where email=?"; ResultSet rs = MyJDBC.query(querySQL, email); try { if(rs.next()){ user.setId(rs.getInt(1)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 注册成功后,发送帐户激活链接 request.getSession().setAttribute("user", user); EmailUtils.sendAccountActivateEmail(user); request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,response); } }
激活账号的Servlet,也就是更新操作
package org.amuxia.emailtest.servlet; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.amuxia.emailtest.pojo.User; import org.amuxia.emailtest.utils.GenerateLinkUtils; import org.amuxia.emailtest.utils.MyJDBC; /** * @author amuxia * 2017年7月24日 */ @WebServlet("/ActivateServlet") public class ActivateServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String idValue = request.getParameter("id"); System.out.println(idValue); int id = -1; try { id = Integer.parseInt(idValue); } catch (NumberFormatException e) { e.printStackTrace(); } String SQL = "select * from tb_user where id=?"; ResultSet rs= MyJDBC.query(SQL, id); User user = new User(); try { if(rs.next()){ user.setId(rs.getInt(1)); user.setUsername(rs.getString(2)); user.setPassword(rs.getString(3)); user.setEmail(rs.getString(4)); user.setActivated(rs.getBoolean(5)); user.setCodeUrl(rs.getString(6)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //验证无误,状态更改为1,即激活 if(GenerateLinkUtils.verifyCheckcode(user, request)){ String updSQL = "update tb_user set activated =1 where id=?"; MyJDBC.execute(updSQL, id); user.setActivated(true); request.getSession().setAttribute("user", user); request.getRequestDispatcher("/WEB-INF/jsp/pass.jsp").forward(request, response); } } }
发送Email的工具类
package org.amuxia.emailtest.utils; import java.util.Date; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message.RecipientType; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import org.amuxia.emailtest.pojo.User; /** * @author amuxia * 2017年7月24日 */ public class EmailUtils { private static final String FROM = "要发送邮件的邮箱,这个例子是163邮箱"; public static void sendAccountActivateEmail(User user) { Session session = getSession(); MimeMessage message = new MimeMessage(session); try { message.setSubject("这是一封激活账号的邮件,复制链接到地址栏来激活他"); message.setSentDate(new Date()); message.setFrom(new InternetAddress(FROM)); message.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail())); message.setContent("<a target='_BLANK' href=''>"+GenerateLinkUtils.generateActivateLink(user)+"</a>","text/html;charset=utf-8"); Transport.send(message); } catch (Exception e) { e.printStackTrace(); } } public static Session getSession() { Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.smtp.host", "smtp.163.com"); props.setProperty("mail.smtp.port", "25"); props.setProperty("mail.smtp.auth", "true"); Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(FROM, "上面邮箱的密码"); } }); return session; } }
这里需要注意一下,以上例子配置的是163邮箱,需要进行邮箱客户端的授权,授权之后,网易邮箱会发来一份客户端授权码作为替代邮箱密码,代码里填写的密码其实是授权码,配置好邮箱最好发一份邮件测试一下,有时程序出问题很可能是邮箱客户端根本发不了邮件
加密账户激活链接生成的工具类
package org.amuxia.emailtest.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.servlet.ServletRequest; import org.amuxia.emailtest.pojo.User; /** * @author amuxia * 2017年7月24日 */ public class GenerateLinkUtils { private static final String CHECK_CODE = "checkCode"; public static String generateActivateLink(User user) { return "http://localhost/EmailDemo/ActivateServlet?id=" + user.getId() + "&" + CHECK_CODE + "=" + generateCheckcode(user); } /** * 生成校验码,用户名+UUID唯一标识符,为安全把他们加密发送 * @param user * @return */ public static String generateCheckcode(User user) { String userName = user.getUsername(); String randomCode = user.getCodeUrl(); return md5(userName + ":" + randomCode); } /** * 接收回来的校验码和发送出去的是不是同一份 * @param user * @param request * @return */ public static boolean verifyCheckcode(User user,ServletRequest request) { String checkCode = request.getParameter(CHECK_CODE); System.out.println(generateCheckcode(user).equals(checkCode)); return true; } private static String md5(String string) { MessageDigest md = null; try { md = MessageDigest.getInstance("md5"); md.update(string.getBytes()); byte[] md5Bytes = md.digest(); return bytes2Hex(md5Bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); System.out.println("md5这里出错了"); } return null; } private static String bytes2Hex(byte[] byteArray) { StringBuffer strBuf = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if(byteArray[i] >= 0 && byteArray[i] < 16) { strBuf.append("0"); } strBuf.append(Integer.toHexString(byteArray[i] & 0xFF)); } return strBuf.toString(); } }
还有一个操作数据库的封装类,MyJDBC,前面博客有写,代码挺长,就不贴了,这是链接:
https://www.jb51.net/article/70107.htm
https://www.jb51.net/article/88647.htm
实体类User
package org.amuxia.emailtest.pojo; public class User { private int id; private String username; private String password; private String email; private boolean activated;//账号状态 private String codeUrl;//激活链接中的随机码 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public boolean isActivated() { return activated; } public void setActivated(boolean activated) { this.activated = activated; } public String getCodeUrl() { return codeUrl; } public void setCodeUrl(String codeUrl) { this.codeUrl = codeUrl; } public User() { super(); } }
注册的jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>注册</title> </head> <body> <form action="/EmailDemo/RegistServlet" method="post"> 用户名:<input type="text" name="username"><br/> 密码:<input type="password" name="password"><br/> 邮箱:<input type="text" name="email"><br/> <input type="submit" value="注册"> </form> </body> </html>
用到的包?
邮箱验证的大概功能就完成了,但是还有很多不足之处,貌似应该设置一个过期时间。等等。。。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
将ResultSet中得到的一行或多行结果集封装成对象的实例
这篇文章主要介绍了将ResultSet中得到的一行或多行结果集封装成对象的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-05-05SpringBoot+WebMagic+MyBaties实现爬虫和数据入库的示例
WebMagic是一个开源爬虫框架,本项目通过在SpringBoot项目中使用WebMagic去抓取数据,最后使用MyBatis将数据入库。具有一定的参考价值,感兴趣的小伙伴们可以参考一下2021-10-10关于JDK+Tomcat+eclipse+MyEclipse的配置方法,看这篇够了
关于JDK+Tomcat+eclipse+MyEclipse的配置问题,很多朋友都搞不太明白,网上一搜配置方法多种哪种最精简呢,今天小编给大家分享一篇文章帮助大家快速掌握JDK Tomcat eclipse MyEclipse配置技巧,需要的朋友参考下吧2021-06-06Springboot2.x+ShardingSphere实现分库分表的示例代码
这篇文章主要介绍了Springboot2.x+ShardingSphere实现分库分表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-10-10spring cloud 之 Feign 使用HTTP请求远程服务的实现方法
下面小编就为大家带来一篇spring cloud 之 Feign 使用HTTP请求远程服务的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-06-06
最新评论