`

关于找回密码

 
阅读更多
原文:http://www.cnblogs.com/zyw-205520/p/3738439.html

通过邮件找回密码功能的实现

1、最近开发一个系统,有个需求就是,忘记密码后通过邮箱找回。现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回。通过java发送邮件的功能我就不说了,重点讲找回密码。



2、参考别人的思路:发送邮件→请求邮件里的URL→验证url→{验证成功修改密码,不成功跳转到失败页面}

重点就是如何生成这个url和如何解析这个url.
需要注意的是一个url只能修改一次密码,当同一帐号发送多封邮件,只有最后一封邮件的url 邮箱



3、加密能防止伪造攻击,一次url只能验证一次,并且绑定了用户。生成url:   可以用UUID生成随机密钥。

数字签名 = MD5(用户名+'′+过期时间+‘’+密钥key)
数据库字段(用户名(主键),密钥key,过期时间)
url参数(用户名,数字签名) ,密钥key的生成:在每一个用户找回密码时候为这个用户生成一个密钥key ,



url example:http://www.wechat68.com:80/CardSSHOK/checkLink?sid=K3xHOi4o/UihH5QYWBDfYA==&userName=123



生成过期时间,生成数字签名,生成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乱码
分享到:
评论

相关推荐

    用户找回密码参考页面

    在IT行业中,用户找回密码的功能是任何Web应用或服务中不可或缺的部分。这个“用户找回密码参考页面”显然是一个设计模板或者指南,旨在帮助开发者或设计师创建一个高效且用户友好的密码重置流程。以下是关于此类...

    C#源码--找回密码

    C#源码--找回密码C#源码--找回密码

    MyQQ 加找回密码窗体

    【MyQQ 加找回密码窗体】是北大青鸟的一个阶段项目,旨在提供一个不仅具备基本聊天功能,还具有特殊安全特性的QQ客户端模拟程序。在该项目中,开发者着重强化了用户体验,尤其是安全性方面,确保用户能够方便地找回...

    项目实战之找回密码(net实现解密找回密码)

    项目实战之找回密码,net实现解密找回密码

    密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回

    密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结密码找回逻辑漏洞总结...

    找回密码(代码)

    找回密码(代码)--这几天收集的!

    JSP找回密码例子

    **JSP找回密码功能详解** 在Web开发中,用户找回密码功能是不可或缺的一部分,它确保了用户在忘记密码时能够安全地重置自己的账户。在这个例子中,我们使用了Java Server Pages (JSP)、JavaBeans和Servlet技术来...

    java邮箱找回密码

    "Java邮箱找回密码"功能是一种常见的用户身份验证机制,它允许用户通过已注册的电子邮件地址重置丢失或忘记的密码。下面将详细介绍如何使用Java来实现这个功能,以及相关的知识点。 首先,我们需要一个用户模型...

    找回密码(jsp)

    【找回密码功能详解】 在Web应用开发中,找回密码功能是一项基本且重要的用户服务,它允许用户在忘记密码时通过邮箱或手机号等验证方式重置密码。本项目以"找回密码(jsp)"为主题,结合了Java、Ajax、SQL等技术,...

    ArcGIS server 找回密码

    ### ArcGIS Server 密码找回与管理指南 #### 一、引言 在日常工作中,很多用户在安装并配置好ArcGIS Server之后,由于工作性质或其他原因,可能会有一段时间不使用该系统。随着时间的推移,很容易忘记之前设置的...

    博客找回密码~

    标题“博客找回密码~”和描述“找回密码~只限博客”显然涉及到的是关于博客平台中用户密码重置的功能。这个功能是任何博客系统中必不可少的一部分,它允许用户在忘记密码时通过一定的验证机制恢复对账户的访问。下面...

    PHP+MYSQL通过邮箱找回密码开发源码

    PHP+MYSQL通过邮箱找回密码开发源码

    邮件找回密码+无刷新验证码

    在网络安全领域,用户账户的安全性至关重要,而"邮件找回密码+无刷新验证码"是一种常见的增强安全性的技术手段。本文将详细解析这两个概念及其在实际应用中的工作原理。 首先,我们来了解一下邮件找回密码机制。当...

    找回密码(简单实用)

    在IT领域,尤其是网络安全与用户认证部分,"找回密码"是一项至关重要的功能。这个功能允许用户在忘记密码时,通过预设的安全机制重新获取账户访问权。本教程将重点讲解如何利用邮箱进行密码找回,这是一个简单且实用...

    找回密码界面

    在这个找回密码界面中,jQuery可能用于监听用户的输入事件,如按键或点击,然后触发AJAX请求验证邮箱或手机号码的正确性。同时,它还可以用来实现表单验证,例如检查输入是否为空,或者格式是否正确。此外,jQuery的...

    linux系统如何找回root密码

    如果我们遗忘了密码,可以使用上述方法来找回密码。但是,为了避免这种情况的出现,我们需要养成良好的密码习惯,例如定期更改密码、使用强密码等。 此外,在使用 Linux 系统时,我们需要了解系统的启动过程和引导...

    增霸卡密码找回.zip

    在找回密码的过程中,用户应避免泄露任何找回密码的过程和结果,以免信息被不法分子截取利用。此外,如果卡片内存储有重要数据,建议用户在进行密码找回之前做好数据备份,以防止在操作过程中出现意外导致数据丢失。...

    密码找回申请表

    - **特殊需求选项**:如“□以后都用此邮箱找回密码□仅此次用此邮箱找回密码”,用于指定未来密码找回的方式。 - **管理员认证规则**:规定了密码格式的具体要求,如长度、字符类型限制等。 - **不予处理情况**:...

    邮箱找回密码java

    以上就是关于“邮箱找回密码java”这一主题的详细知识点,涵盖了从使用JavaMail API发送邮件到实现完整的密码找回流程所需的技术点。在实际开发中,还需要考虑用户体验、性能优化以及与现有系统的集成等因素。

    PHP找回密码机制流程

    首先,找回密码过程通常包括以下几个步骤: 1. 用户输入邮箱或用户名:当用户忘记密码时,他们会在网站上输入注册时使用的邮箱或用户名。这是验证用户身份的第一步,因为这个信息通常是唯一的。 2. 发送验证链接:...

Global site tag (gtag.js) - Google Analytics