การใช้ฟังก์ชันการกู้คืนรหัสผ่านผ่านอีเมล
1. เมื่อเร็ว ๆ นี้ฉันได้พัฒนาระบบและฉันมีข้อกำหนดในการดึงข้อมูลผ่านอีเมลของฉันหลังจากลืมรหัสผ่าน ทุกวันนี้ระบบจะบังคับให้อีเมลป้อนที่อยู่อีเมลเมื่อลงทะเบียน หนึ่งในวัตถุประสงค์คือการดึงข้อมูลผ่านการเชื่อมโยงอีเมลและคุณสามารถดึงรหัสผ่านได้ ฉันจะไม่พูดถึงฟังก์ชั่นการส่งอีเมลผ่าน Java แต่มุ่งเน้นไปที่การดึงรหัสผ่าน
2. อ้างถึงแนวคิดของคนอื่น: ส่งอีเมล→ขอ URL ในอีเมล→ตรวจสอบ URL → {ตรวจสอบการแก้ไขรหัสผ่านสำเร็จ แต่ข้ามไปที่หน้าล้มเหลวหากล้มเหลว}
ประเด็นคือวิธีสร้าง URL นี้และวิธีการแยกวิเคราะห์ URL นี้
ควรสังเกตว่า URL สามารถแก้ไขรหัสผ่านได้เพียงครั้งเดียว เมื่อมีการส่งอีเมลหลายฉบับโดยบัญชีเดียวกันจะมีที่อยู่อีเมล URL ของอีเมลล่าสุดเท่านั้น
3. การเข้ารหัสสามารถป้องกันการโจมตีโดยการปลอมแปลง URL สามารถตรวจสอบได้เพียงครั้งเดียวและผูกมัดผู้ใช้ สร้าง URL: คุณสามารถใช้ UUID เพื่อสร้างคีย์แบบสุ่ม
Digital Signature = MD5 (ชื่อผู้ใช้ +'' +เวลาหมดอายุ +'' +เวลาหมดอายุ +'' +คีย์คีย์)
ฟิลด์ฐานข้อมูล (ชื่อผู้ใช้ (คีย์หลัก), คีย์คีย์, เวลาหมดอายุ)
พารามิเตอร์ URL (ชื่อผู้ใช้, ลายเซ็นดิจิตอล), การสร้างคีย์: สร้างคีย์คีย์สำหรับผู้ใช้แต่ละคนเมื่อดึงรหัสผ่าน
สร้างเวลาหมดอายุสร้างลายเซ็นดิจิตอลสร้าง URL และส่งอีเมล Addu (ชื่อผู้ใช้, คีย์, เวลาหมดอายุ)
ฐานข้อมูลที่ใช้มีดังนี้:
รหัสผ่านเพื่อดึงที่อยู่อีเมลมีดังนี้:
แพ็คเกจ com.soq.card.web.action; นำเข้า java.sql.timestamp นำเข้า java.util.list; นำเข้า java.util.uuid; นำเข้า org.hibernate.criteria; นำเข้า org.hibernate.session; org.springframework.orm.hibernate3.hibernatetemplate; นำเข้า com.soq.card.biz.userhander; นำเข้า com.soq.card.entity.users; นำเข้า com.soq.card.tools.dbhepler; com.soq.card.web.base.baseaction;/** * @author javen * @email [email protected] * */passemailaction คลาสสาธารณะขยาย baseaction {ผู้ใช้ส่วนตัว; Userhander ส่วนตัว Userhander; อีเมลสตริงส่วนตัว สตริงส่วนตัว SID; ชื่อผู้ใช้สตริงส่วนตัว; สตริงสาธารณะ sendmail () {ลอง {hibernatetemplate ht = this.getuserhander (). getusersdao (). gethibernatetemplate (); SessionFactory Factory = ht.getSessionFactory (); เซสชั่นเซสชัน = Factory.opensession (); เกณฑ์เกณฑ์ = session.createCriteria (users.class); Criteria.add (ข้อ จำกัด eq ("loginName", อีเมล)); รายการ <ผู้ใช้> list = criteria.list (); if (list.size ()> 0) {users = list.get (0); Mail Mail = New Mail (); String SecretKey = UUID.RANDOMUUID (). TOSTRING (); // คีย์ timestamp outdate = timestamp ใหม่ (System.currentTimeMillis () + 30 * 60 * 1000); // หมดอายุหลังจากวันที่ยาวนาน 30 นาที = ล้าสมัย getTime ()/ 1000 * 1000; string sql = "ผู้ใช้อัปเดตตั้งค่า outdate =?, validatacode =? ที่ไหน loginName =?;"; string str [] = {outdate+"", secretkey, users.getLoginName ()}; bhepler.addu (sql, str); //this.getuserhander().getusersdao().getHibernatetemplate().Update(users); // บันทึกลงในฐานข้อมูล System.out.println ("ชื่อผู้ใช้ >>>>"+users.getUserName ()); String key = users.getUserName () + "$" + วันที่ + "$" + SecretKey; System.out.println ("คีย์ >>>"+คีย์); String 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'>" + resetPasshref + "</a> หรือ <a href =" มากกว่า 30 นาที mail.setto (อีเมล); mail.setFrom ("xx"); // ที่อยู่อีเมลของคุณ Mail.sethost ("smtp.163.com"); mail.setUserName ("[email protected]"); // user mail.setPassword ("cxxx"); // รหัสผ่าน Mail.SetSubject ("[QR Code Code Business นามบัตร] ดึงรหัสผ่านบัญชีของคุณ"); mail.setContent (EmailContent); if (mail.sendmail ()) {system.out.println ("ส่งแบบส่ง")); this.getRequest (). setAttribute ("mesg", "การรีเซ็ตรหัสผ่านอีเมลถูกส่งแล้วโปรดลงชื่อเข้าใช้ที่อยู่อีเมลเพื่อรีเซ็ต!"); กลับ "Sendmail"; }} else {this.getRequest (). setAttribute ("mesg", "ชื่อผู้ใช้ไม่มีอยู่คุณจะไม่ลืมกล่องจดหมายของคุณใช่มั้ย"); กลับ "Nouser"; }} catch (exception 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 (users.class); Criteria.add (ข้อ จำกัด eq ("ชื่อผู้ใช้", ชื่อผู้ใช้)); รายการ <ผู้ใช้> list = criteria.list (); if (list.size ()> 0) {users = list.get (0); timestamp outdate = (timestamp) users.getOutdate (); System.out.println ("ล้าสมัย >>>"+ล้าสมัย); if (outdate.getTime () <= system.currentTimeMillis ()) {// หมายความว่า this.getRequest (). setAttribute ("mesg", "ลิงก์หมดอายุโปรดใช้รหัสผ่านอีกครั้ง"); System.out.println ("เวลาหมดเวลา"); ส่งคืน "ข้อผิดพลาด"; } string key = users.getUserName ()+"$"+outdate.getTime ()/1000*1000+"$"+users.getValidataCode (); // ระบบลายเซ็นดิจิตอล. String DigitalsIgnature = MD5.MD5 (คีย์); // Signature System.out.println ("Digitalsignature >>>>>"+Digitalsignature); if (! digitalsignature.equals (sid)) {this.getRequest (). setAttribute ("mesg", "ลิงก์ไม่ถูกต้องมันหมดอายุหรือไม่? System.out.println ("ฉลากไม่ถูกต้อง"); ส่งคืน "ข้อผิดพลาด"; } else {// การตรวจสอบลิงก์คือการไปที่หน้าแก้ไขรหัสผ่าน this.getRequest (). setAttribute ("ผู้ใช้" ผู้ใช้); กลับ "ความสำเร็จ"; }} else {this.getRequest (). setAttribute ("mesg", "ลิงก์ไม่ถูกต้องผู้ใช้ที่จับคู่ไม่สามารถพบได้โปรดนำไปใช้ใหม่เพื่อดึงรหัสผ่าน"); System.out.println ("ผู้ใช้ไม่มีอยู่"); ส่งคืน "ข้อผิดพลาด"; }} ผู้ใช้สาธารณะ getUsers () {ผู้ใช้ส่งคืน; } public void setusers (ผู้ใช้ผู้ใช้) {this.users = ผู้ใช้; } Public UserHander GetUserHander () {return userhander; } โมฆะสาธารณะ SetUserHander (UserHander UserHander) {this.UserHander = UserHander; } สตริงสาธารณะ getEmail () {ส่งคืนอีเมล; } โมฆะสาธารณะ setEmail (อีเมลสตริง) {this.email = อีเมล; } สตริงสาธารณะ getSid () {return sid; } โมฆะสาธารณะ setSID (สตริง sid) {this.sid = sid; } สตริงสาธารณะ getUserName () {ส่งคืนชื่อผู้ใช้; } โมฆะสาธารณะ setUserName (ชื่อผู้ใช้สตริง) {this.userName = ชื่อผู้ใช้; -
ภาคผนวก 1: ความแม่นยำของมิลลิวินาทีจะหายไปเมื่อบันทึกข้อมูล ตัวอย่างเช่น: 2014-05-20 10: 30: 10.234 เมื่อเก็บไว้ในฐานข้อมูล MySQL จะกลายเป็น 2013-05-20 10: 30: 10.0 เวลาแตกต่างกันและการจับคู่ SID จะไม่เท่ากัน ดังนั้นฉันจึงทำการดำเนินการที่ไม่สนใจความถูกต้อง
ภาคผนวก 2: แก้ปัญหารหัสภาษาจีนที่อ่านไม่ออกในชื่อด้านล่าง Linux
sun.misc.base64encoder enc = new sun.misc.base64encoder (); mailmessage.setsubject (mimeutility.encodetext (mailinfo.getsubject (), "UTF-8", "B")); // แก้ปัญหาจดหมาย Linux
ภาคผนวก 3: ทำไมคุณไม่ใส่ SID ลงในตารางผู้ใช้โดยตรง มันจะโอเคที่จะเปรียบเทียบ SID โดยตรงเมื่อตรวจสอบ
ซอร์สโค้ดดาวน์โหลดที่อยู่: http://pan.baidu.com/s/1cl8hkq
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น