최근에 저는 시스템을 개발했으며 비밀번호를 잊어 버린 후 이메일을 통해 시스템을 검색해야합니다. 요즘 시스템은 등록 할 때 이메일이 이메일 주소를 입력하도록 강요합니다. 목적 중 하나는 이메일 바인딩을 통해이를 검색하고 비밀번호를 검색하는 것입니다. Java를 통해 이메일을 보내는 기능에 대해서는 이야기하지 않고 비밀번호 검색에 중점을 둡니다.
다른 사람의 아이디어를 참조하십시오 : 이메일 보내기 → 이메일에서 URL 요청 → URLS 확인 → {비밀번호를 성공적으로 수정하지만 성공하지 못한 상태에서 실패한 페이지로 이동하십시오}
요점은이 URL을 생성하는 방법 과이 URL을 구문 분석하는 방법입니다.
URL은 비밀번호를 한 번만 수정할 수 있습니다. 동일한 계정으로 여러 이메일이 전송되면 마지막 이메일의 URL 만
암호화는 위조 공격을 방지 할 수 있습니다. URL은 한 번만 확인하고 사용자를 바인딩 할 수 있습니다. URL 생성 : UUID를 사용하여 임의의 키를 생성 할 수 있습니다.
디지털 서명 = MD5 (사용자 이름 +'$' +만료 시간 +'$' +키 키)
데이터베이스 필드 (사용자 이름 (기본 키), 키 키, 만료 시간)
URL 매개 변수 (사용자 이름, 디지털 서명), 키 생성 : 비밀번호를 검색 할 때 각 사용자의 키 키를 생성합니다.
URL 예 : http : // localhost : 8080/user/reset_password? sid = d62d6a23fbf86ffe696b593d55351a54aea77 & username = test4
만료 시간을 생성하고, 디지털 서명을 생성하고, URL을 생성하고, 이메일을 보내십시오. SaverOrupDate (사용자 이름, 키 키, 만료 시간)
다음은 SpringMVC 코드입니다
@RequestMapping (value = "/user/i_forget_password") @ResponseBody public map forkingpass (httpservletRequest 요청, 문자열 사용자 이름) {users users = usererVice.finduserByName (username); 맵 맵 = new Hashmap <string, String> (); 문자열 msg = ""; if (user == null) {// 사용자 이름이 존재하지 않습니다 msg = "사용자 이름이 존재하지 않으면 사용자 이름을 잊지 못할 것입니다."; map.put ( "msg", msg); 리턴 맵; } try {String secretkey = uuid.randomuuid (). toString (); // key timestamp outdate = new Timestamp (System.CurrentTimeMillis ()+30*60*1000); // 30 분 후 만료 날짜 = OutDate.getTime ()/1000*1000; // milliseconds users.setValidatacode (SecretKey)를 무시합니다. user.setRegisterDate (OutDate); userervice.update (사용자); // 데이터베이스 문자열에 저장 key = user.getUserName ()+"$"+date+"$"+SecretKey; 문자열 digitalsignature = md5.md5encode (key); // 디지털 서명 문자열 이메일 title = "YouFang 클라우드 비밀번호 검색"; 문자열 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 = "이 이메일에 응답하지 마십시오. 아래 링크를 클릭하여 비밀번호를 재설정하려면 <br/> <a href ="+resetpasshref+"target = '_ blank'> 비밀번호를 재설정하려면 저를 클릭하십시오 </a>"+"<br/> 팁 :이 이메일이 30 분을 초과하면 링크가 만료되면 '+key+"/t+"/t+"+key+"+key+"+이시야. System.out.print (ResetPassHref); sendmail.getInstatnce (). sendhtmlmail (emailTitle, emailContent, users.getEmail ()); MSG = "조작이 성공했으며 비밀번호 복구 링크가 이메일 주소로 전송되었습니다. 30 분 이내에 비밀번호를 재설정하십시오"; loginfo (요청, 사용자 이름, "비밀번호 검색 응용 프로그램"); } catch (예외 e) {e.printstacktrace (); msg = "이메일이 존재하지 않습니까? 알 수없는 오류, 관리자에게 연락하십시오."; } map.put ( "msg", msg); 리턴 맵; }링크가 이메일 주소로 전송되었습니다. 이메일 주소를 입력하고 링크를 클릭하십시오
다음은 링크 확인 코드입니다. 비밀번호 수정 인터페이스로 점프하여 실패한 인터페이스로 점프하여 확인하십시오.
@requestmapping (value = "/user/resteet_password", method = requestmethod.get) public modelandview checkResetLink (string sid, String username) {modelAndView model = new ModelAndView ( "error"); 문자열 msg = ""; if (sid.equals ( "") || username.equals ( "") {msg = "링크가 불완전합니다."; model.adoBject ( "msg", msg); loginfo (사용자 이름, "암호 링크 검색"); 리턴 모델; } user users = userervice.finduserByName (username); if (user == null) {msg = "링크가 잘못되었고 일치하는 사용자를 찾을 수 없습니다. 비밀번호를 검색하기 위해 다시 적용하십시오."; model.adoBject ( "msg", msg); loginfo (사용자 이름, "비밀번호 복구 링크가 유효하지 않음"); 리턴 모델; } timestamp outdate = user.getRegisterDate (); if (outdate.gettime () <= system.currenttimeMillis ()) {// msg가 만료되었음을 의미합니다. "링크가 만료되었으므로 비밀번호를 검색하기 위해 다시 신청하십시오."; model.adoBject ( "msg", msg); loginfo (사용자 이름, "암호 링크 검색"); 리턴 모델; } string key = users.getUername ()+"$"+outDate.getTime ()/1000*1000+"$"+users.getValidatacode (); // 디지털 서명 문자열 digitalSignature = md5.md5encode (키); System.out.println (key+"/t"+digitalsignature); if (! digitalSignature.equals (sid)) {msg = "링크가 올바르지 않고 만료 되었습니까? Repaply"; model.adoBject ( "msg", msg); loginfo (사용자 이름, "비밀번호 복구 링크가 유효하지 않음"); 리턴 모델; } model.setViewName ( "user/reset_password"); // 비밀번호 모델을 수정하려면 인터페이스로 돌아갑니다 .addoBject ( "username", username); 리턴 모델; }보충 1 : 타임 스탬프 유형 객체의 밀리 초 정확도는 데이터에 저장되면 손실됩니다. 예 : 2013-10-08 10 : 29 : 10.234 MySQL 데이터베이스에 저장되면 2013-10-08 10 : 29 : 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를 직접 비교해도 괜찮습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.