@@ -32,6 +32,32 @@ public Map<String, Object> resetPassword(String email, String password) {
3232 clearCache(user. getId());
3333 return map;
3434}
35+
36+ // 重置密码邮箱验证码:
37+ public Map<String , Object > getForgetCode(String email) {
38+ Map<String , Object > map = new HashMap<> ();
39+ if (StringUtils . isBlank(email)) {
40+ map. put(" emailMsg" , " 邮箱不能为空!" );
41+ return map;
42+ }
43+ User user = userMapper. selectByEmail(email);
44+ if (user == null ) {
45+ map. put(" emailMsg" , " 该邮箱不存在!" );
46+ return map;
47+ }
48+ if (user. getStatus() == 0 ) {
49+ map. put(" emailMsg" , " 该邮箱未激活!" );
50+ }
51+ // 发送邮件
52+ Context context = new Context ();
53+ context. setVariable(" email" , email);
54+ String code = CommunityUtil . genUUID(). substring(0 , 4 );
55+ context. setVariable(" verifyCode" , code);
56+ String content = templateEngine. process(" /mail/forget" , context);
57+ mailClient. sendMail(email, " 找回密码" , content);
58+ map. put(" verifyCode" , code);
59+ return map;
60+ }
3561```
3662
37632 . LoginController:
@@ -42,11 +68,35 @@ public String getForgetPage(){
4268 return " /site/forget" ;
4369}
4470
71+ // 邮箱验证码
72+ @RequestMapping (path = " /forget/code" , method = RequestMethod . GET )
73+ @ResponseBody
74+ public String getForgetCode(String email, HttpSession session) {
75+ Map<String , Object > map = userService. getForgetCode(email);
76+ if (map. containsKey(" verifyCode" )) {
77+ // 保存验证码,注意这里要对不同的邮箱保存不同的验证码,防止换邮箱后验证码还是之前的
78+ session. setAttribute(email + " _verifyCode" , map. get(" verifyCode" ));
79+ return CommunityUtil . getJSONString(0 );
80+ } else {
81+ return CommunityUtil . getJSONString(1 , (String ) map. get(" emailMsg" ));
82+ }
83+ }
84+
4585@RequestMapping (path = " /forgetPassword" , method = RequestMethod . POST )
46- public String updatePassword(String email, String password ,Model model){
86+ public String resetPassword(String email, String verifyCode, String password, Model model, HttpSession session) {
87+ // 检查验证码
88+ String code = (String ) session. getAttribute(email + " _verifyCode" );
89+ if (StringUtils . isBlank(verifyCode) || StringUtils . isBlank(code) || ! code. equalsIgnoreCase(verifyCode)) {
90+ // 验证码错误,返回重置密码页面
91+ model. addAttribute(" codeMsg" , " 验证码错误!" );
92+ return " /site/forget" ;
93+ }
94+
4795 Map<String , Object > map = userService. resetPassword(email, password);
4896 if (map == null || map. isEmpty()) {
49- return " redirect:/logout" ;
97+ model. addAttribute(" msg" , " 重置密码成功,正在前往登录页面,请重新登录!" );
98+ model. addAttribute(" target" , " /login" );
99+ return " /site/operate-result" ;
50100 } else {
51101 model. addAttribute(" emailMsg" , map. get(" emailMsg" ));
52102 model. addAttribute(" passwordMsg" , map. get(" passwordMsg" ));
@@ -66,68 +116,135 @@ forget.html:
66116``` html
67117<!doctype html>
68118<html lang =" en" xmlns:th =" https://www.thymeleaf.org" >
119+ <head >
120+ <meta charset =" utf-8" >
121+ <meta name =" viewport" content =" width=device-width, initial-scale=1, shrink-to-fit=no" >
122+ <meta name =" _csrf" th:content =" ${_csrf.token}" >
123+ <meta name =" _csrf_header" th:content =" ${_csrf.headerName}" >
124+ <link rel =" icon" th:href =" @{/img/icon.png}" />
125+ <link rel =" stylesheet" type =" text/css" th:href =" @{/css/bootstrap.min.css}" />
126+ <link rel =" stylesheet" th:href =" @{/css/global.css}" />
127+ <link rel =" stylesheet" th:href =" @{/css/login.css}" />
128+ <title >忘记密码</title >
129+ </head >
130+ <body >
131+ <div class =" nk-container" >
132+ <!-- 头部 -->
133+ <header class =" bg-dark sticky-top" th:replace =" index::header" >
134+ </header >
135+
136+ <!-- 内容 -->
137+ <div class =" main" >
138+ <div class =" container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3" >
139+ <form class =" mt-5" th:action =" @{/forgetPassword}" method =" post" >
140+ <div class =" form-group row" >
141+ <label for =" your-email" class =" col-sm-2 col-form-label text-right" >邮箱:</label >
142+ <div class =" col-sm-10" >
143+ <input type =" email" th:class =" |form-control ${emailMsg!=null?'is-invalid':''}|"
144+ th:value =" ${param.email}"
145+ id =" your-email" placeholder =" 请输入您的邮箱!" name =" email" required >
146+ <div class =" invalid-feedback" th:text =" ${emailMsg}" >
147+ 该邮箱已被注册!
148+ </div >
149+ </div >
150+ </div >
151+ <div class =" form-group row mt-4" >
152+ <label for =" verifycode" class =" col-sm-2 col-form-label text-right" >验证码:</label >
153+ <div class =" col-sm-6" >
154+ <input type =" text" th:class =" |form-control ${codeMsg!=null?'is-invalid':''}|"
155+ th:value =" ${param.verifyCode}" name =" verifyCode" id =" verifycode"
156+ placeholder =" 请输入验证码!" >
157+ <div class =" invalid-feedback" th:text =" ${codeMsg}" >
158+ 验证码不正确!
159+ </div >
160+ </div >
161+ <div class =" col-sm-4" >
162+ <a href =" javascript:;" id =" verifyCodeBtn" class =" btn btn-info form-control" >获取验证码</a >
163+ </div >
164+ </div >
165+ <div class =" form-group row mt-4" >
166+ <label for =" your-password" class =" col-sm-2 col-form-label text-right" >新密码:</label >
167+ <div class =" col-sm-10" >
168+ <input type =" password" th:class =" |form-control ${passwordMsg!=null?'is-invalid':''}|"
169+ th:value =" ${param.password}"
170+ id =" your-password" placeholder =" 请输入新的密码!" name =" password" required >
171+ <div class =" invalid-feedback" th:text =" ${passwordMsg}" >
172+ 密码长度不能小于8位!
173+ </div >
174+ </div >
175+ </div >
176+ <div class =" form-group row mt-4" >
177+ <div class =" col-sm-2" ></div >
178+ <div class =" col-sm-10 text-center" >
179+ <button type =" submit" class =" btn btn-info text-white form-control" >重置密码</button >
180+ </div >
181+ </div >
182+ </form >
183+ </div >
184+ </div >
185+
186+ <!-- 尾部 -->
187+ <footer class =" bg-dark" th:replace =" index::footer" >
188+ </footer >
189+ </div >
190+
191+ <script th:src =" @{/js/jquery-3.1.0.min.js}" ></script >
192+ <script type =" module" th:src =" @{/js/popper.min.js}" ></script >
193+ <script th:src =" @{/js/bootstrap.min.js}" ></script >
194+ <script th:src =" @{/js/global.js}" ></script >
195+ <script th:src =" @{/js/forget.js}" ></script >
196+ </body >
197+ </html >
198+ ```
199+
200+ forget.js:
201+
202+ ``` javascript
203+ $ (function (){
204+ $ (" #verifyCodeBtn" ).click (getVerifyCode);
205+ });
206+
207+ function getVerifyCode () {
208+ var email = $ (" #your-email" ).val ();
209+
210+ if (! email) {
211+ alert (" 请先填写您的邮箱!" );
212+ return false ;
213+ }
214+
215+ $ .get (
216+ CONTEXT_PATH + " /forget/code" ,
217+ {" email" : email},
218+ function (data ) {
219+ data = $ .parseJSON (data);
220+ if (data .code == 0 ) {
221+ alert (" 验证码已发送至您的邮箱,请登录邮箱查看!" );
222+ } else {
223+ alert (data .msg );
224+ }
225+ }
226+ );
227+ }
228+ ```
229+
230+ 邮箱内容:
231+
232+ ``` html
233+ <!doctype html>
234+ <html lang =" en" xmlns:th =" http://www.thymeleaf.org" >
69235<head >
70236 <meta charset =" utf-8" >
71- <meta name =" viewport" content =" width=device-width, initial-scale=1, shrink-to-fit=no" >
72- <meta name =" _csrf" th:content =" ${_csrf.token}" >
73- <meta name =" _csrf_header" th:content =" ${_csrf.headerName}" >
74- <link rel =" icon" th:href =" @{/img/icon.png}" />
75- <link rel =" stylesheet" type =" text/css" th:href =" @{/css/bootstrap.min.css}" />
76- <link rel =" stylesheet" th:href =" @{/css/global.css}" />
77- <link rel =" stylesheet" th:href =" @{/css/login.css}" />
78237 <title >忘记密码</title >
79238</head >
80239<body >
81- <div class =" nk-container" >
82- <!-- 头部 -->
83- <header class =" bg-dark sticky-top" th:replace =" index::header" >
84- </header >
85-
86- <!-- 内容 -->
87- <div class =" main" >
88- <div class =" container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3" >
89- <form class =" mt-5" th:action =" @{/forgetPassword}" method =" post" >
90- <div class =" form-group row" >
91- <label for =" your-email" class =" col-sm-2 col-form-label text-right" >邮箱:</label >
92- <div class =" col-sm-10" >
93- <input type =" email" th:class =" |form-control ${emailMsg!=null?'is-invalid':''}|"
94- th:value =" ${param.email}"
95- id =" your-email" placeholder =" 请输入您的邮箱!" name =" email" required >
96- <div class =" invalid-feedback" th:text =" ${emailMsg}" >
97- 该邮箱已被注册!
98- </div >
99- </div >
100- </div >
101- <div class =" form-group row mt-4" >
102- <label for =" your-password" class =" col-sm-2 col-form-label text-right" >新密码:</label >
103- <div class =" col-sm-10" >
104- <input type =" password" th:class =" |form-control ${passwordMsg!=null?'is-invalid':''}|"
105- th:value =" ${param.password}"
106- id =" your-password" placeholder =" 请输入新的密码!" name =" password" required >
107- <div class =" invalid-feedback" th:text =" ${passwordMsg}" >
108- 密码长度不能小于8位!
109- </div >
110- </div >
111- </div >
112- <div class =" form-group row mt-4" >
113- <div class =" col-sm-2" ></div >
114- <div class =" col-sm-10 text-center" >
115- <button type =" submit" class =" btn btn-info text-white form-control" >重置密码</button >
116- </div >
117- </div >
118- </form >
119- </div >
120- </div >
121-
122- <!-- 尾部 -->
123- <footer class =" bg-dark" th:replace =" index::footer" >
124- </footer >
125- </div >
126-
127- <script th:src =" @{/js/jquery-3.1.0.min.js}" ></script >
128- <script type =" module" th:src =" @{/js/popper.min.js}" ></script >
129- <script th:src =" @{/js/bootstrap.min.js}" ></script >
130- <script th:src =" @{/js/global.js}" ></script >
240+ <div >
241+ <p >
242+ <
b th:text =
" ${email}" >
[email protected] </
b >, 您好!
243+ </p >
244+ <p >
245+ 您正在找回账号的密码,本次操作的验证码为 <b th:text =" ${verifyCode}" >u5s6dt</b >,请您及时设置新密码!
246+ </p >
247+ </div >
131248</body >
132249</html >
133250```
0 commit comments