通过邮件找回密码功能的实现
1、最近开发一个系统,有个需求就是,忘记密码后通过邮箱找回。现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回。通过java发送邮件的功能我就不说了,重点讲找回密码。
2、参考别人的思路:发送邮件→请求邮件里的URL→验证url→{验证成功修改密码,不成功跳转到失败页面}
重点就是如何生成这个url和如何解析这个url.
需要注意的是一个url只能修改一次密码,当同一帐号发送多封邮件,只有最后一封邮件的url 邮箱
3、加密能防止伪造攻击,一次url只能验证一次,并且绑定了用户。生成url: 可以用UUID生成随机密钥。
数字签名 = MD5(用户名+'′+过期时间+‘′+过期时间+‘'+密钥key)
数据库字段(用户名(主键),密钥key,过期时间)
url参数(用户名,数字签名) ,密钥key的生成:在每一个用户找回密码时候为这个用户生成一个密钥key ,
生成过期时间,生成数字签名,生成url,发送邮件. AddU(用户名,密钥key,过期时间)
使用到的数据库如下 :
找回邮箱密码代码如下:
package com.soq.card.web.action; import java.sql.Timestamp; import java.util.List; import java.util.UUID; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Restrictions; import org.springframework.orm.hibernate3.HibernateTemplate; import com.soq.card.biz.UserHander; import com.soq.card.entity.Users; import com.soq.card.tools.DBhepler; import com.soq.card.tools.Mail; import com.soq.card.tools.Md5; import com.soq.card.web.base.BaseAction; /** * @author javen * @Email zyw205@gmail.com * */ public class PassEmailAction extends BaseAction { private Users users; private UserHander userHander; private String email; private String sid; private String userName; public String sendmail() { try { HibernateTemplate ht = this.getUserHander().getUsersDAO().getHibernateTemplate(); SessionFactory factory = ht.getSessionFactory(); Session sesshtml" target="_blank">ion = factory.openSession(); Criteria criteria = session.createCriteria(Users.class); criteria.add(Restrictions.eq("loginName", email)); List<Users> list = criteria.list(); if (list.size() > 0) { users=list.get(0); Mail mail = new Mail(); String secretKey = UUID.randomUUID().toString(); // 密钥 Timestamp outDate = new Timestamp(System.currentTimeMillis() + 30 * 60 * 1000);// 30分钟后过期 long date = outDate.getTime() / 1000 * 1000;// 忽略毫秒数 mySql 取出时间是忽略毫秒数的 DBhepler bhepler=new DBhepler(); String sql="update users set outDate=?,validataCode=? where loginName=?;"; String str[] ={outDate+"",secretKey,users.getLoginName()}; bhepler.AddU(sql, str); //this.getUserHander().getUsersDAO().getHibernateTemplate().update(users); // 保存到数据库 System.out.println(" UserName>>>> "+users.getUserName()); String key =users.getUserName() + "$" + date + "$" + secretKey; System.out.println(" key>>>"+key); String digitalSignature = Md5.md5(key);// 数字签名 String path = this.getRequest().getContextPath(); String basePath = this.getRequest().getScheme() + "://" + this.getRequest().getServerName() + ":" + this.getRequest().getServerPort() + path + "/"; String resetPassHref = basePath + "checkLink?sid=" + digitalSignature +"&userName="+users.getUserName(); String emailContent = "请勿回复本邮件.点击下面的链接,重设密码<br/><a href=" + resetPassHref + " target='_BLANK'>" + resetPassHref + "</a> 或者 <a href=" + resetPassHref + " target='_BLANK'>点击我重新设置密码</a>" + "<br/>tips:本邮件超过30分钟,链接将会失效,需要重新申请'找回密码'" + key + "\t" + digitalSignature; mail.setTo(email); mail.setFrom("XX");// 你的邮箱 mail.setHost("smtp.163.com"); mail.setUsername("XXX@163.com");// 用户 mail.setPassword("CXXX");// 密码 mail.setSubject("[二维码名片]找回您的账户密码"); mail.setContent(emailContent); if (mail.sendMail()) { System.out.println(" 发送成功"); this.getRequest().setAttribute("mesg", "重置密码邮件已经发送,请登陆邮箱进行重置!"); return "sendMail"; } } else { this.getRequest().setAttribute("mesg", "用户名不存在,你不会忘记邮箱了吧?"); return "noUser"; } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; } public String checkResetLink() { System.out.println("sid>>>" + sid); if (sid.equals("") || userName.equals("")) { this.getRequest().setAttribute("mesg", "链接不完整,请重新生成"); System.out.println(">>>>> null"); return "error"; } HibernateTemplate ht = this.getUserHander().getUsersDAO().getHibernateTemplate(); SessionFactory factory = ht.getSessionFactory(); Session session = factory.openSession(); Criteria criteria = session.createCriteria(Users.class); criteria.add(Restrictions.eq("userName", userName)); List<Users> list = criteria.list(); if (list.size()>0) { users=list.get(0); Timestamp outDate = (Timestamp) users.getOutDate(); System.out.println("outDate>>>"+outDate); if(outDate.getTime() <= System.currentTimeMillis()){ //表示已经过期 this.getRequest().setAttribute("mesg", "链接已经过期,请重新申请找回密码."); System.out.println("时间 超时"); return "error"; } String key = users.getUserName()+"$"+outDate.getTime()/1000*1000+"$"+users.getValidataCode();//数字签名 System.out.println("key link》》"+key); String digitalSignature = Md5.md5(key);// 数字签名 System.out.println("digitalSignature>>>>"+digitalSignature); if(!digitalSignature.equals(sid)) { this.getRequest().setAttribute("mesg", "链接不正确,是否已经过期了?重新申请吧."); System.out.println("标示不正确"); return "error"; }else { //链接验证通过 转到修改密码页面 this.getRequest().setAttribute("user", users); return "success"; } }else { this.getRequest().setAttribute("mesg", "链接错误,无法找到匹配用户,请重新申请找回密码."); System.out.println("用户不存在"); return "error"; } } public Users getUsers() { return users; } public void setUsers(Users users) { this.users = users; } public UserHander getUserHander() { return userHander; } public void setUserHander(UserHander userHander) { this.userHander = userHander; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
补充1:Timestamp类型对象在保存到数据的时候 毫秒精度会丢失。比如:2014-05-20 10:30:10.234 存到mysql数据库的时候 变成 2013-05-20 10:30:10.0。时间变得不相同了,sid 匹配的时候不会相等。 所以我做了忽略精度的操作。
补充2:解决linux下面title中文乱码
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(), "UTF-8", "B")); //解决linux邮件title乱码
补充3:怎么不直接把sid插入到users表呢。验证的时候直接比较sid就ok了。
源码下载地址:http://pan.baidu.com/s/1cl8hKq
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍java实现通过绑定邮箱找回密码功能,包括了java实现通过绑定邮箱找回密码功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java实现通过绑定邮箱找回密码功能,供大家参考,具体内容如下 1.输入用户名及验证码,验证用户名是否存在 (1).生成验证码工具类 (2).生成验证码action 2.用户名验证通过后往绑定邮箱发送邮件 3.邮件发送成功后进入邮箱,通过该链接
本文向大家介绍thinkphp实现发送邮件密码找回功能实例,包括了thinkphp实现发送邮件密码找回功能实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了thinkphp实现发送邮件密码找回功能的方法。分享给大家供大家参考。具体实现方法如下: 首先下载mail.class.php类文件,配置文件中定义下列参数: 在tp项目org中放入mail.class.php,使用时候引入 impo
本文向大家介绍Django实现发送邮件找回密码功能,包括了Django实现发送邮件找回密码功能的使用技巧和注意事项,需要的朋友参考一下 在各大网站上,一定都遇到过找回密码的问题,通常采用的方式是通过发送带有验证码的邮件进行身份验证,本文将介绍通过Django实现邮件找回密码功能。 找回密码流程 功能流程: 1.首先在用户登录界面,添加“忘记密码”链接 2.生成随机验证码,发送邮件到用户信息中填写邮
本文向大家介绍Java实现邮箱发送功能实例(阿里云邮箱推送),包括了Java实现邮箱发送功能实例(阿里云邮箱推送)的使用技巧和注意事项,需要的朋友参考一下 前言 绑定阿里云域名,创建域名账户,并配置解析域名账户,获得发送邮箱的权限,上限两百封,超出要¥… 阿里云邮件推送控制台 https://www.aliyun.com/product/directmail 申请邮箱并解析域名 https://y
本文向大家介绍JavaWeb利用邮箱帮用户找回密码,包括了JavaWeb利用邮箱帮用户找回密码的使用技巧和注意事项,需要的朋友参考一下 本文是介绍在一个小的JAVAWeb项目中,利用邮箱帮用户找回密码。 效果展示 需要一个发送邮件的jar包 : javax.mail .jar 1.JSP页面(设置邮箱输入框) 2.Servlet代码(根据用户输入的邮箱账号找到用户,并生成发送邮件类的实例,再
本文向大家介绍Java实现MD5加密及解密的代码实例分享,包括了Java实现MD5加密及解密的代码实例分享的使用技巧和注意事项,需要的朋友参考一下 基础:MessageDigest类的使用 其实要在Java中完成MD5加密,MessageDigest类大部分都帮你实现好了,几行代码足矣: 进阶:加密及解密类 Java实现MD5加密以及解密类,附带测试类,具体见代码。 MD5加密解密类——MyMD5