이메일을 통한 비밀번호 복구 기능 구현
1. 최근에, 나는 시스템을 개발했으며 비밀번호를 잊어 버린 후에는 이메일을 통해 시스템을 검색해야합니다. 요즘 시스템은 등록 할 때 이메일이 이메일 주소를 입력하도록 강요합니다. 목적 중 하나는 이메일 바인딩을 통해이를 검색하고 비밀번호를 검색하는 것입니다. Java를 통해 이메일을 보내는 기능에 대해서는 이야기하지 않고 비밀번호 검색에 중점을 둡니다.
2. 다른 사람의 아이디어를 참조하십시오 : 이메일 보내기 → 이메일에서 URL 요청 URL 요청 → URL 확인 → {비밀번호를 성공적으로 수정하지만 실패한 페이지로 이동하면}}
요점은이 URL을 생성하는 방법 과이 URL을 구문 분석하는 방법입니다.
URL은 비밀번호를 한 번만 수정할 수 있습니다. 동일한 계정으로 여러 이메일이 전송되면 마지막 이메일의 URL 이메일 주소 만 있습니다.
3. 암호화는 위조 공격을 방지 할 수 있습니다. URL은 한 번만 확인하고 사용자를 바인딩 할 수 있습니다. URL 생성 : UUID를 사용하여 임의의 키를 생성 할 수 있습니다.
디지털 서명 = MD5 (사용자 이름 +'' +만료 시간 +'' +만료 시간 +'' +키 키)
데이터베이스 필드 (사용자 이름 (기본 키), 키 키, 만료 시간)
URL 매개 변수 (사용자 이름, 디지털 서명), 키 생성 : 비밀번호를 검색 할 때 각 사용자의 키 키를 생성합니다.
만료 시간을 생성하고, 디지털 서명을 생성하고, URL을 생성하고, 이메일을 보내십시오. addu (사용자 이름, 키, 만료 시간)
사용 된 데이터베이스는 다음과 같습니다.
이메일 주소를 검색하는 비밀번호는 다음과 같습니다.
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.ssession factory; import org.hibernate.criterion 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.card.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool.tool com.soq.card.web.base.baseaction;/** * @author javen * @email [email protected] * */public class passeMailAction은 {개인 사용자 사용자; 개인 사용자 hander userhander; 개인 문자열 이메일; 개인 문자열 sid; 개인 문자열 사용자 이름; public String sendmail () {try {hibernateTemplate ht = this.getUserHander (). getUsersDao (). gethibernateTemplate (); SessionFactory Factory = ht.getSessionFactory (); 세션 세션 = factory.opensession (); 기준 기준 = session.createCriteria (user.class); criteria.add (gestrictions.eq ( "loginname", email)); 목록 <users> list = criteria.list (); if (list.size ()> 0) {user = list.get (0); 메일 메일 = 새 메일 (); 문자열 secretkey = uuid.randomuuid (). toString (); // key timestamp outdate = new Timestamp (System.CurrentTimeMillis () + 30 * 60 * 1000); // 30 분 후에 만료되었습니다. 문자열 sql = "업데이트 사용자가 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.getUername () + "$" + date + "$" + secretkey; System.out.println ( "키 >>>"+키); 문자열 digitalsignature = md5.md5 (키); // 디지털 서명 문자열 경로 = 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'>"_ _ blank '> " + resetpasshref +"</a> 또는 <a href = " + resetpasshref +"target ='_ blank '> 비밀번호 </a> </az </az </az </az </az </az </a> " 30 분. '검색 암호' " + key +"/t " + digitalsignature를 사용해야합니다. mail.setto (이메일); mail.setfrom ( "xx"); // 귀하의 이메일 주소 mail.sethost ( "smtp.163.com"); mail.setusername ( "[email protected]"); // user mail.setpassword ( "cxxx"); // password mail.setsubject ( "[QR 코드 비즈니스] 계정 암호 검색"); Mail.SetContent (emailContent); if (mail.sendmail ()) {system.out.println ( "sendsuccessly send"); this.getRequest (). setAttribute ( "mesg", "이메일이 전송 된 비밀번호 재설정, 이메일 주소에 로그인하여 재설정하십시오!"); "sendmail"을 반환합니다. }} else {this.getRequest (). setAttribute ( "mesg", "사용자 이름이 존재하지 않으면 사서함을 잊지 않을 것입니다."); "Nouser"를 반환합니다. }} catch (예외 e) {// todo : 핸들 예외 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"); "오류"를 반환합니다. } hibernateTemplate ht = this.getUserHander (). getUsersDao (). gethibernateTemplate (); SessionFactory Factory = ht.getSessionFactory (); 세션 세션 = factory.opensession (); 기준 기준 = session.createCriteria (user.class); criteria.add (equaltions.eq ( "username", username)); 목록 <users> list = criteria.list (); if (list.size ()> 0) {user = 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 ( "시간 타임 아웃"); "오류"를 반환합니다. } string key = users.getUername ()+"$"+outDate.getTime ()/1000*1000+"$"+users.getValidatacode (); // digital signature system.out.println ( "키 링크》"+키); 문자열 digitalsignature = md5.md5 (key); // 디지털 서명 시스템.out.println ( "digitalsignature >>>>"+digitalsignature); if (! digitalSignature.equals (sid)) {this.getRequest (). setAttribute ( "mesg", "링크가 잘못되었고 만료 되었습니까? Repapply"); System.out.println ( "잘못된 레이블"); "오류"를 반환합니다. } else {// 링크 확인은 비밀번호 수정 페이지로 이동하는 것입니다. "성공"을 반환합니다. }} else {this.getRequest (). setAttribute ( "mesg", "링크가 잘못되었고 일치하는 사용자를 찾을 수 없으므로 암호를 검색하려면 다시 적용하십시오."); System.out.println ( "사용자가 존재하지 않음"); "오류"를 반환합니다. }} 공개 사용자 getUsers () {반환 사용자; } public void setUsers (사용자 사용자) {this.users = 사용자; } public userHander getUserHander () {return userHander; } public void setUserHander (userhander userhander) {this.userhander = userhander; } public String getEmail () {반환 이메일; } public void seteMail (문자열 이메일) {this.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 : 데이터를 저장할 때 밀리 초 정확도가 손실됩니다. 예 : 2014-05-20 10 : 30 : 10.234 MySQL 데이터베이스에 저장되면 2013-05-20 10 : 30 : 10.0이됩니다. 시간이 다르고 SID 경기는 같지 않습니다. 그래서 정확도를 무시한 작업을 수행했습니다.
Supplement 2 : Linux 아래의 타이틀에서 중국어가 달린 코드 해결
Sun.Misc.Base64Encoder ENC = New Sun.Misc.Base64Encoder (); MailMessage.setSubject (MimeUtility.encodetext (MailInfo.getSubject (), "UTF-8", "B"); // Linux 메일 제목을 해결합니다
Supplement 3 : SID를 사용자 테이블에 직접 삽입하지 않는 이유는 무엇입니까? 확인할 때 SID를 직접 비교해도 괜찮습니다.
소스 코드 다운로드 주소 : http://pan.baidu.com/s/1cl8hkq
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.