English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
I recently developed a system, and there is a requirement to retrieve the password through email after forgetting it. The current system forces the input of email during registration, one of the purposes is to bind the email for password retrieval, and password retrieval can be performed. I won't talk about the function of sending email in Java, the focus is on password retrieval.
Refer to others' ideas: send email → request URL in the email → verify URL → {if verified, change password, if not, jump to the failure page}
The key point is how to generate this URL and how to parse this URL.
It should be noted that a URL can only be modified once, when the same account sends multiple emails, only the URL in the last email
Encryption can prevent forgery attacks, a URL can only be verified once, and it is bound to the user. Generate URL: Random key can be generated using UUID.
digital signature = MD5(username+’$’+expiration time+‘$'+key)
Database fields (username (primary key), key, expiration time)
URL parameters (username, digital signature), generation of key: A key is generated for each user when the user retrieves the password,
URL example: http://localhost:8080/user/reset_password#63;sid=D622D6A23FBF86FFE696B593D55351A54AEAEA77&userName=test4
Generate expiration time, generate digital signature, generate URL, send email. saveOrUpdate(username, key, expiration time)
The following is springMvc code
@RequestMapping(value = "/user/i_forget_password" @ResponseBody public Map forgetPass(HttpServletRequest request, String userName){ Users users = userService.findUserByName(userName); Map map = new HashMap<String, String>(); String msg = ""; if(users == null){ //Username does not exist msg = "Username does not exist, did you forget your username?&63;"; map.put("msg",msg); return map; } try{ String secretKey= UUID.randomUUID().toString(); //key Timestamp outDate = new Timestamp(System.currentTimeMillis()+30*60*1000);//3expires after 0 minutes long date = outDate.getTime()/1000*1000; //ignore milliseconds users.setValidataCode(secretKey); users.setRegisterDate(outDate); userService.update(users); //save to database String key = users.getUserName()+"$"+date+"$"+secretKey; String digitalSignature = MD5.MD5Encode(key); //Digital Signature String emailTitle = "Password Reset for YouFang Cloud"; String path = request.getContextPath(); String basePath = request.getScheme()+://"+request.getServerName()+:"+request.getServerPort()+path+"/"; String resetPassHref = basePath+"user/reset_password#63;sid="+digitalSignature;+"&userName="+users.getUserName(); String emailContent = "Do not reply to this email. Click the link below to reset your password<br/><a href="+resetPassHref +" target='_BLANK'>Click here to reset your password</a>" + "<br/>tips: This email exceeds30 minutes, the link will expire, and you need to apply for 'password reset' again"+key;+"\t"+digitalSignature; System.out.print(resetPassHref); SendMail.getInstatnce().sendHtmlMail(emailTitle, emailContent, users.getEmail()); msg = "Operation successful, the password reset link has been sent to your email. Please go to3Reset password within 0 minutes"; logInfo(request,userName,"Apply to reset password"); } e.printStackTrace(); msg="Email does not exist? Unknown error, please contact the administrator."; } map.put("msg",msg); return map; }
The reset link has been sent to your email. Please open the link in your email
The following is the link verification code, if verified, jump to the password change interface, otherwise jump to the failure interface
@RequestMapping(value = "/user/reset_password", method = RequestMethod.GET) public ModelAndView checkResetLink(String sid,String userName){ ModelAndView model = new ModelAndView("error"); String msg = ""; if(sid.equals("") || userName.equals("")){ msg="Incomplete link, please regenerate."; model.addObject("msg",msg) ; logInfo(userName,"Password reset link expired"); return model; } Users users = userService.findUserByName(userName); if(users == null){ msg = "Link error, cannot find matching user, please reapply to reset your password."; model.addObject("msg",msg) ; logInfo(userName,"Password reset link expired"); return model; } Timestamp outDate = users.getRegisterDate(); if(outDate.getTime() <= System.currentTimeMillis()){ //Indicates that it has expired msg = "The link has expired, please reapply to reset your password."; model.addObject("msg",msg) ; logInfo(userName,"Password reset link expired"); return model; } String key = users.getUserName()+"$"+outDate.getTime()/1000*1000+"$"+users.getValidataCode(); //Digital Signature String digitalSignature = MD5.MD5Encode(key); System.out.println(key+"\t"+digitalSignature); if(!digitalSignature.equals(sid)) { msg = "The link is incorrect, has it expired?"63"Reapply"; model.addObject("msg",msg) ; logInfo(userName,"Password reset link expired"); return model; } model.setViewName("user/reset_password"); //Return to the change password interface model.addObject("userName",userName); return model; }
Supplementary1:The millisecond accuracy will be lost when the Timestamp type object is saved. For example:2013-10-08 10:29:10.234 When stored in the mysql database, it becomes 2013-10-08 10:29:10.0. The time becomes different, and sid will not be equal when matched. So I did the operation of ignoring accuracy.
Supplementary2:Solve the title Chinese garbled code under Linux
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(), "UTF-8", "B"); //Solve the title garbled code of Linux mail
Supplementary3:Why not directly insert sid into the user table? The verification can be done by comparing sid directly.
That's all for this article, I hope it will be helpful to everyone's learning, and I also hope everyone will support the Yelling Tutorial more.
Statement: The content of this article is from the Internet, the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been edited by humans, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)