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

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

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

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

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

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

url example: http://localhost:8080/user/reset_password?sid=D622D6A23FBF86FFE696B593D55351A54AEAEA77&userName=test4

生成过期时间,生成数字签名,生成url,发送邮件. saveOrUpdate(用户名,密钥key,过期时间)

以下为springMvc代码

 1  @RequestMapping(value = "/user/i_forget_password")
 2     @ResponseBody
 3     public Map forgetPass(HttpServletRequest request,String userName){
 4         Users users = userService.findUserByName(userName);
 5         Map map = new HashMap<String ,String >();
 6         String msg = "";
 7         if(users == null){              //用户名不存在
 8             msg = "用户名不存在,你不会忘记用户名了吧?";
 9             map.put("msg",msg);
10             return map;
11         }
12         try{
13             String secretKey= UUID.randomUUID().toString();  //密钥
14             Timestamp outDate = new Timestamp(System.currentTimeMillis()+30*60*1000);//30分钟后过期
15             long date = outDate.getTime()/1000*1000;                  //忽略毫秒数
16             users.setValidataCode(secretKey);
17             users.setRegisterDate(outDate);
18             userService.update(users);    //保存到数据库
19             String key = users.getUserName()+"$"+date+"$"+secretKey;
20             String digitalSignature = MD5.MD5Encode(key);                 //数字签名
21
22             String emailTitle = "有方云密码找回";
23             String path = request.getContextPath();
24             String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
25             String resetPassHref =  basePath+"user/reset_password?sid="+digitalSignature+"&userName="+users.getUserName();
26             String emailContent = "请勿回复本邮件.点击下面的链接,重设密码<br/><a href="+resetPassHref +" target=‘_BLANK‘>点击我重新设置密码</a>" +
27                     "<br/>tips:本邮件超过30分钟,链接将会失效,需要重新申请‘找回密码‘"+key+"\t"+digitalSignature;
28             System.out.print(resetPassHref);
29             SendMail.getInstatnce().sendHtmlMail(emailTitle,emailContent,users.getEmail());
30             msg = "操作成功,已经发送找回密码链接到您邮箱。请在30分钟内重置密码";
31             logInfo(request,userName,"申请找回密码");
32         }catch (Exception e){
33             e.printStackTrace();
34             msg="邮箱不存在?未知错误,联系管理员吧。";
35         }
36         map.put("msg",msg);
37         return map;
38     }

找回链接已经发到邮箱了。进入邮箱点开链接

以下为链接检验代码,验证通过 跳转到修改密码界面,否则跳转到失败界面

 1 @RequestMapping(value = "/user/reset_password",method = RequestMethod.GET)
 2     public ModelAndView checkResetLink(String sid,String userName){
 3         ModelAndView model = new ModelAndView("error");
 4         String msg = "";
 5         if(sid.equals("") || userName.equals("")){
 6             msg="链接不完整,请重新生成";
 7             model.addObject("msg",msg) ;
 8             logInfo(userName,"找回密码链接失效");
 9             return model;
10         }
11         Users users = userService.findUserByName(userName);
12         if(users == null){
13             msg = "链接错误,无法找到匹配用户,请重新申请找回密码.";
14             model.addObject("msg",msg) ;
15             logInfo(userName,"找回密码链接失效");
16             return model;
17         }
18         Timestamp outDate = users.getRegisterDate();
19         if(outDate.getTime() <= System.currentTimeMillis()){         //表示已经过期
20             msg = "链接已经过期,请重新申请找回密码.";
21             model.addObject("msg",msg) ;
22             logInfo(userName,"找回密码链接失效");
23             return model;
24         }
25         String key = users.getUserName()+"$"+outDate.getTime()/1000*1000+"$"+users.getValidataCode();          //数字签名
26         String digitalSignature = MD5.MD5Encode(key);
27         System.out.println(key+"\t"+digitalSignature);
28         if(!digitalSignature.equals(sid)) {
29             msg = "链接不正确,是否已经过期了?重新申请吧";
30             model.addObject("msg",msg) ;
31             logInfo(userName,"找回密码链接失效");
32             return model;
33         }
34         model.setViewName("user/reset_password");  //返回到修改密码的界面
35         model.addObject("userName",userName);
36         return model;
37     }

补充1:Timestamp类型对象在保存到数据的时候 毫秒精度会丢失。比如:2013-10-08 10:29:10.234 存到mysql数据库的时候 变成 2013-10-08 10:29:10.0。时间变得不相同了,sid 匹配的时候不会相等。 所以我做了忽略精度的操作。

补充2:解决linux下面title中文乱码

1   sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
2   mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(), "UTF-8", "B"));      //解决linux邮件title乱码

补充3:怎么不直接把sid插入到user表呢。验证的时候直接比较sid就ok了。

时间: 2024-08-06 11:16:38

SpringMVC通过邮件找回密码功能的实现的相关文章

PHP会员找回密码功能实现实例介绍

设置思路 1.用户注册时需要提供一个E-MAIL邮箱,目的就是用该邮箱找回密码. 2.当用户忘记密码或用户名时,点击登录页面的“找回密码”超链接,打开表单,并输入注册用的E-MAIL邮箱,提交. 3.系统通过该邮箱,从数据库中查找到该用户信息,并更新该用户的密码为一个临时密码(比如:12345678). 4.系统借助Jmail功能把该用户的信息发送到该用户的邮箱中(内容包括:用户名.临时密码.提醒用户及时修改临时密码的提示语). 5.用户用临时密码即可登录. HTML 我们在找回密码的页面上放置

用户邮件找回密码实现

改天我在写详细注释吧,代码先贴出来,注释很明白了,应该无需多言. 1 Controller代码: 2 public ActionResult ForgotPassword() 3 { 4 return View(); 5 } 6 [ActionName("ForgotPassword"),HttpPost] 7 public ActionResult ForgotPasswordPost(ForgotPasswordModel model) 8 { 9 if (ModelState.I

Jsp邮件找回密码全攻略

[来源网络  http://www.2cto.com/kf/201502/376374.html] 一般大型网站我们登录的时候,密码忘了都有个功能可以找回密码. 细数下大致的方法: 1.直接把密码发送到你的邮箱去.一般是临时密码. 2.短信验证,成本较高. 3.密保问题 4.发送一个链接到你邮箱点击即可更改密码. 个人认为第四种方法最经济实惠,这次也主要都是在搞这个. 搞了一个晚上,单单邮件发送功能写了快300行,虽然很多是注释和空格,被舍友一说,用python只写了20几行,不禁膜拜PYTHO

网站开发之用户重设密码 找回密码功能的实现原理

网站开发之用户重设密码 找回密码功能的实现原理,这个东西基本在现在每个系统中都带有的功能,但是实现的方式也是挺多的,这个是跟数据库没多大关系的方法嘞. 用户流程: 1.用户忘记密码,来到密码重设界面 2.用户输入Email地址,点击重设密码按钮 3.用户收到一封密码重设邮件,里面有重设密码的链接,此链接有过期时间 4.用户点击链接,来到密码重设页面,输入新密码,完成 这个流程并没有什么创新,很多网站都是用这套流程 后端实现方式: 1.当用户输入Email地址后,验证这个Email,如果存在于数据

找回密码功能的实现(考虑安全性,加密方面)

最近负责公司的登陆与注册模块,大部分已经实现了,这找回密码功能实现的思路是这样的 1.用户忘记密码,需要找回密码 2.后台通过一系列的加密处理,将通过后台邮件将重置密码的页面发送到该用户的邮箱 3.用户通过邮箱里烦人链接就可以重置密码. 以下是代码 /* ------------------------------------------忘记密码,发送邮件------------------------------------------------- */ //找回密码发送邮件功能 @Requ

通过邮件找回密码

前言 本文将介绍忘记密码时通过发送重置密码邮件找回密码的实现思路.整个实现过程中最重要的就是以下三点: 如何发送邮件到用户指定邮箱 邮件中的重置密码链接构成是怎么样的 验证重置密码链接的合法性(是否过期) 先来个实现的效果展示吧,然后再仔细分析如何去实现各个部分: 效果展示 (这里盗用下我们小组作品成果的前端) 用户输入注册时的邮箱账户获取重置密码的链接 用户登录自己的邮箱查看邮件 用户点击重置密码链接,如果在重置链接有效期内我们跳转到重置密码界面,否则提醒用户该链接已过期 如何发送邮件给用户指

简述邮箱找回密码功能

1. 在登录页面给个链接,在找回密码界面可以输入邮箱地址和验证码,验证码是为了防止恶意找回: 2. 后台,首先判断验证码是否正确,再判断该邮箱是否注册过用户; 3. 如果该邮箱存在,检索出该用户信息; 4. 如果你的密码没有MD5加密的话,可以直接查询出密码,如果MD5加密了,只能重新生成一个密码,并修改该用户: 5. 将新生成的密码发送到用户邮箱里,用JavaMail发送邮件;

C#实现发送邮件找回密码功能

首先我们来分析一下思路: 三步走: 1.先要发送邮件 2.让用户点击邮件里的URL 3.实现修改密码 1.为了保证安全性,需要生成发送到邮件的URL,主要参数(用户名,过期时间,key(key 需要在每次运行是自动生成随机码), IP等等)   然后将URL发送到邮箱. 2.保存发送的参数(建议保存在数据库) 3.解析url:首先根据用户名从数据库中查找出密钥key和过期时间,没有则表示该请求 是伪造的或者过期的,然后验证签名,验证过期时间,都验证通过,就可以修改密码, 密码修改完以后,删除数据

用户找回密码功能JS验证邮箱通过点击下一步隐藏邮箱输入框并修改下一步按钮的ID

//这里是BaseDao 1 /** 2 * 获得一个对象 3 * @param hql 4 * @param param 5 * @return 6 */ 7 public Object get(String hql, Object[] param){ 8 List<Object> objects = this.getHibernateTemplate().find(hql, param); 9 if (objects != null && objects.size() &g