这里有新鲜出炉的Java并发编程示例,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
本篇文章主要介绍了Java实现邮箱找回密码实例代码,可以通过邮箱找回丢失密码,具有一定的参考价值,有需要的可以了解一下。
通过邮件找回密码功能的实现
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 session = 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
来源: http://www.phperz.com/article/17/1129/359512.html