Recently developed a system, there is a need to forget the password after the mailbox back. Now the system in the registration will be forced to enter the mailbox, and its purpose is to be retrieved through the mail binding, you can retrieve the password. The function of sending mail through Java I will not say, focus on the return password.
Refer to other people's thinking: Send mail → request url→ Verify url→{Verify successfully modify password, unsuccessful jump to failed page}
The point is how to generate this URL and how to parse the URL.
Note that a URL can only be changed once the password, when the same account to send more than one message, only the last email URL
Encryption prevents forgery attacks, once URLs can only be authenticated once, and the user is bound. Generate URL: An accompanying secret key can be generated with a UUID.
Digital signature = MD5 (username + ' $ ' + expiration + ' $ ' + key)
Database fields (user name (primary key), keys key, expiration time)
URL parameters (user name, digital signature), the creation of key keys: Each user to retrieve the password time for the user to generate a key keys,
URL Example:http://localhost:8080/user/reset_password?sid=d622d6a23fbf86ffe696b593d55351a54aeaea77&username =test4
Generates an expiration time, generates a digital signature, generates a URL, and sends a message. Saveorupdate (username, key, expiration time)
The following is the SPRINGMVC code
@RequestMapping (value = "/user/i_forget_password") @ResponseBody public Map forgetpass (HttpServletRequest request,str
ing userName) {Users users = Userservice.finduserbyname (userName);
Map map = new hashmap<string, String > ();
String msg = "";
if (users = null) {//user name does not exist MSG = "Username does not exist, you will not forget the username?";
Map.put ("msg", MSG);
return map; } try{String secretkey= uuid.randomuuid (). toString ();//key Timestamp outdate = new Timestamp (System.curre Nttimemillis () +30*60*1000);//30 minutes after expiration long date = Outdate.gettime ()/1000*1000;
Ignores Users.setvalidatacode (secretkey) of milliseconds;
Users.setregisterdate (outdate); Userservice.update (users);
Save to database String key = Users.getusername () + "$" +date+ "$" +secretkey; String digitalsignature = MD5. Md5encode (key);
Digital signature String Emailtitle = "have Fang password retrieve";
String path = Request.getcontextpath (); String basepath = request.getscheme () + "://" +request. getServerName () + ":" +request.getserverport () +path+ "/";
String resetpasshref = basepath+ "user/reset_password?sid=" +digitalsignature+ "&username=" +users.getUserName (); String emailcontent = "Do not reply to this message." Click the link below to reset the password <br/><a href= "+resetpasshref +" target= ' _blank ' > click I reset Password <
/a> "+" <br/>tips: This message more than 30 minutes, link will be invalidated, need to reapply ' retrieve password ' "+key+" T "+digitalsignature;
System.out.print (RESETPASSHREF);
Sendmail.getinstatnce (). Sendhtmlmail (Emailtitle,emailcontent,users.getemail ()); msg = "Operation successful, has sent back password link to your mailbox."
Please reset the password within 30 minutes ";
Loginfo (Request,username, "Apply for retrieve password");
}catch (Exception e) {e.printstacktrace (); msg= "Mailbox does not exist? Unknown error, contact admin Bar.
";
} map.put ("MSG", MSG);
return map;
}
Find the link has been sent to the mailbox. Access to the mailbox point open link
The following is a link-checking code that jumps to the failed interface by jumping to the Modify password interface
@RequestMapping (value = "/user/reset_password", method = requestmethod.get) public Modelandview Checkresetlink (String s
Id,string userName) {Modelandview model = new Modelandview ("error");
String msg = ""; if (Sid.equals ("") | |
Username.equals ("")) {msg= "link incomplete, please regenerate";
Model.addobject ("msg", MSG);
Loginfo (userName, "Retrieve Password link invalid");
return model;
Users users = Userservice.finduserbyname (userName);
if (users = null) {msg = "link error, unable to find a matching user, please reapply for password.";
Model.addobject ("msg", MSG);
Loginfo (userName, "Retrieve Password link invalid");
return model;
} Timestamp outdate = Users.getregisterdate ();
if (Outdate.gettime () <= System.currenttimemillis ()) {//indicates expired msg = "The link has expired, please reapply to retrieve the password.";
Model.addobject ("msg", MSG);
Loginfo (userName, "Retrieve Password link invalid");
return model; The 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?" Re-apply it ";
Model.addobject ("msg", MSG);
Loginfo (userName, "Retrieve Password link invalid");
return model; } model.setviewname ("User/reset_password");
Return to the interface Model.addobject ("UserName", UserName) to modify the password;
return model;
}
Add 1: Timestamp type objects are lost in millisecond precision when they are saved to data. For example: 2013-10-08 10:29:10.234 into the MySQL database when the 2013-10-08 10:29:10.0. Time has changed, and Sid matches are not equal. So I did an operation that ignores precision.
Add 2: solve Linux under title Chinese garbled
Sun.misc.BASE64Encoder enc = new Sun.misc.BASE64Encoder ();
Mailmessage.setsubject (Mimeutility.encodetext (Mailinfo.getsubject (), "UTF-8", "B")); Solve Linux Message title garbled
Add 3: Why not just insert the SID into the user table? It's OK to compare SIDS directly when validating.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.