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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 用AJAX实现页面登陆以及注册用户名验证的简单实例

    AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX 是一种用于创建快速动态网页的技术.其核心是 JavaScript 对象 XMLHttpRequest.该对象在 Internet Explorer 5 中首次引入,它是一种支持异步请求的技术.简而言之,XMLHttpRequest使您可以使用 JavaScript 向服务器提出请求并处理响应,而不阻塞用户. 通过在后台与

  • 根据输入邮箱号跳转到相应登录地址的解决方法

    话不多说,跟着小编一起来看下具体的实现代码吧 <script> var hash={ 'qq.com':'http://mail.qq.com', 'gmail.com': 'http://mail.google.com', 'sina.com': 'http://mail.sina.com.cn', '163.com': 'http://mail.163.com', '126.com': 'http://mail.126.com', 'yeah.net': 'http://www.yeah.

  • 微信小程序-详解微信登陆、微信支付、模板消息

    微信公众平台近日悄然开始内测微信小程序(微信公众号)功能,引来无数开发者和普通用户关注,微信支付的能力,是随着小程序的发布一并推出的,具有介绍如下: wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要依赖会话密钥完成. OBJECT参数说明: success返回参数说明: 示例代码: //app.js App({ onLaunch: functio

  • js表单登陆验证示例

    本文实例讲述了js表单登陆验证的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

  • jQuery验证手机号邮箱身份证的正则表达式(含港澳台)

    自己对正则验证也没系统用过,这次自己做个demo,一下子把这些全都用上了,下次有需要直接来拿了. 以下代码是在页面使用JQuery进行验证的,也有在后台进行验证的,可以试试,都一样的原理. 直接上代码:注意:(有些验证规则当然不仅仅是本文的,也许还有其他更好的,可以留言交流) 手机号:(移动-电信-联通) var tel = $("#PhoneNumber").val();//获取输入的手机号 var yidongreg = /^(134[012345678]\d{7}|1[34578

  • php实现登陆模块功能示例

    本文实例讲述了php实现登陆模块功能的方法.分享给大家供大家参考,具体如下: 最近在学习php.学了一点关于登陆的东西,写下来备忘. 新建四个页面,分别命名为: login.php check.php index.php error.php login页面用表单建立一个登陆页面,不多说了.在代码里用js脚本判断用户名和密码不能为空,为空则重置焦点.代码如下: <script type="text/JavaScript"> function jc() { var userNa

  • 如何验证会员系统中用户的邮箱是否真实存在

    在开发网站时,我们需要对用户注册的邮箱进行核对与验证,用户填写的邮箱是否有效邮箱. 好吧,我们先从数据库入手,修改用户表让用户有填写email的字段,添加了2个字段: ALTER TABLE [dbo].[Users] ADD [Email] VARCHAR(100) NULL, [IsVerify] BIT NOT NULL DEFAULT(0) SELECT * FROM [dbo].[Users] 由于你需要做2个功能,一个是要求用户验证邮箱有效性,也有可以以邮箱来让用户修改用户密码.因此

  • JavaWeb登陆功能实现代码

    本文实例为大家分享了JavaWeb登陆功能的方法,供大家参考,具体内容如下 首先我们要JavaWeb登陆的基本流程:JSP页面发送请求-->Servlet-->Servlet通过调用方法从数据库中得到数据并将结果返回页面. 我们先建立三个jsp页面,包括login.jsp(登陆页面).index.jsp(显示登陆成功后的信息).error.jsp(登录失败的页面),其中后两个页面的内容可以随意写,而login.jsp页面的主要内容如下: <form action="LoginS

  • jquery css实现邮箱自动补全

    今天在公司做一个电子商务网站的注册会员时,要求用户在电子邮箱文本框中输入时,给与热点提示常用的电子邮箱,帮助用户选择,提高体验效果.下面是用Jquery+css实现的邮箱自动补全,供大家参考和学习. HTML代码:emailAutoComple.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>邮箱自动补全&l

  • 在js中实现邮箱格式的验证方法(推荐)

    如下所示: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>在此处插入标题</title> <script typ

  • jQuery实现邮箱下拉列表自动补全功能

    记得,在上个项目中,遇到这样一个需求,网站要求填写邮箱的时候,还没有填写完,就会出现一系列下拉列表,帮助自动补全邮箱的功能.今天小编给给大家分享下我基于jquery是怎么实现此功能的! 功能简述 •填写邮箱名字,出现下拉列表,自动补全邮箱 •点击上下按键,选取下拉列表邮箱 •按回车键,选中列表内容,隐藏下拉列表 •鼠标经过,下拉列表选项设置为高亮 •鼠标点击,选中下拉列表选项,隐藏下拉列表 HTML HTML代码很简单,我们就一个简单的输入框,然后一个ul标签,在内部可以放好多li标签. <ht

随机推荐