Skip to content

Commit

Permalink
completed forget password
Browse files Browse the repository at this point in the history
  • Loading branch information
1517005260 committed Jun 6, 2024
1 parent c6b482f commit 6806ee4
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 78 deletions.
235 changes: 176 additions & 59 deletions help/2-LoginAndRegister/7-AccountSetting/7.2-ForgetPassword.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,32 @@ public Map<String, Object> resetPassword(String email, String password) {
clearCache(user.getId());
return map;
}

// 重置密码邮箱验证码:
public Map<String, Object> getForgetCode(String email) {
Map<String, Object> map = new HashMap<>();
if (StringUtils.isBlank(email)) {
map.put("emailMsg", "邮箱不能为空!");
return map;
}
User user = userMapper.selectByEmail(email);
if (user == null) {
map.put("emailMsg", "该邮箱不存在!");
return map;
}
if (user.getStatus() == 0) {
map.put("emailMsg", "该邮箱未激活!");
}
// 发送邮件
Context context = new Context();
context.setVariable("email", email);
String code = CommunityUtil.genUUID().substring(0, 4);
context.setVariable("verifyCode", code);
String content = templateEngine.process("/mail/forget", context);
mailClient.sendMail(email, "找回密码", content);
map.put("verifyCode", code);
return map;
}
```

2. LoginController:
Expand All @@ -42,11 +68,35 @@ public String getForgetPage(){
return "/site/forget";
}

// 邮箱验证码
@RequestMapping(path = "/forget/code", method = RequestMethod.GET)
@ResponseBody
public String getForgetCode(String email, HttpSession session) {
Map<String, Object> map = userService.getForgetCode(email);
if (map.containsKey("verifyCode")) {
// 保存验证码,注意这里要对不同的邮箱保存不同的验证码,防止换邮箱后验证码还是之前的
session.setAttribute(email + "_verifyCode", map.get("verifyCode"));
return CommunityUtil.getJSONString(0);
} else {
return CommunityUtil.getJSONString(1, (String) map.get("emailMsg"));
}
}

@RequestMapping(path = "/forgetPassword", method = RequestMethod.POST)
public String updatePassword(String email, String password ,Model model){
public String resetPassword(String email, String verifyCode, String password, Model model, HttpSession session) {
// 检查验证码
String code = (String) session.getAttribute(email + "_verifyCode");
if (StringUtils.isBlank(verifyCode) || StringUtils.isBlank(code) || !code.equalsIgnoreCase(verifyCode)) {
// 验证码错误,返回重置密码页面
model.addAttribute("codeMsg", "验证码错误!");
return "/site/forget";
}

Map<String, Object> map = userService.resetPassword(email, password);
if (map == null || map.isEmpty()) {
return "redirect:/logout";
model.addAttribute("msg", "重置密码成功,正在前往登录页面,请重新登录!");
model.addAttribute("target", "/login");
return "/site/operate-result";
} else {
model.addAttribute("emailMsg", map.get("emailMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
Expand All @@ -66,68 +116,135 @@ forget.html:
```html
<!doctype html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
<link rel="icon" th:href="@{/img/icon.png}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}" />
<link rel="stylesheet" th:href="@{/css/global.css}" />
<link rel="stylesheet" th:href="@{/css/login.css}" />
<title>忘记密码</title>
</head>
<body>
<div class="nk-container">
<!-- 头部 -->
<header class="bg-dark sticky-top" th:replace="index::header">
</header>

<!-- 内容 -->
<div class="main">
<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
<form class="mt-5" th:action="@{/forgetPassword}" method="post">
<div class="form-group row">
<label for="your-email" class="col-sm-2 col-form-label text-right">邮箱:</label>
<div class="col-sm-10">
<input type="email" th:class="|form-control ${emailMsg!=null?'is-invalid':''}|"
th:value="${param.email}"
id="your-email" placeholder="请输入您的邮箱!" name="email" required>
<div class="invalid-feedback" th:text="${emailMsg}">
该邮箱已被注册!
</div>
</div>
</div>
<div class="form-group row mt-4">
<label for="verifycode" class="col-sm-2 col-form-label text-right">验证码:</label>
<div class="col-sm-6">
<input type="text" th:class="|form-control ${codeMsg!=null?'is-invalid':''}|"
th:value="${param.verifyCode}" name="verifyCode" id="verifycode"
placeholder="请输入验证码!">
<div class="invalid-feedback" th:text="${codeMsg}">
验证码不正确!
</div>
</div>
<div class="col-sm-4">
<a href="javascript:;" id="verifyCodeBtn" class="btn btn-info form-control">获取验证码</a>
</div>
</div>
<div class="form-group row mt-4">
<label for="your-password" class="col-sm-2 col-form-label text-right">新密码:</label>
<div class="col-sm-10">
<input type="password" th:class="|form-control ${passwordMsg!=null?'is-invalid':''}|"
th:value="${param.password}"
id="your-password" placeholder="请输入新的密码!" name="password" required>
<div class="invalid-feedback" th:text="${passwordMsg}">
密码长度不能小于8位!
</div>
</div>
</div>
<div class="form-group row mt-4">
<div class="col-sm-2"></div>
<div class="col-sm-10 text-center">
<button type="submit" class="btn btn-info text-white form-control">重置密码</button>
</div>
</div>
</form>
</div>
</div>

<!-- 尾部 -->
<footer class="bg-dark" th:replace="index::footer">
</footer>
</div>

<script th:src="@{/js/jquery-3.1.0.min.js}"></script>
<script type="module" th:src="@{/js/popper.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/js/global.js}"></script>
<script th:src="@{/js/forget.js}"></script>
</body>
</html>
```

forget.js:

```javascript
$(function(){
$("#verifyCodeBtn").click(getVerifyCode);
});

function getVerifyCode() {
var email = $("#your-email").val();

if(!email) {
alert("请先填写您的邮箱!");
return false;
}

$.get(
CONTEXT_PATH + "/forget/code",
{"email":email},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
alert("验证码已发送至您的邮箱,请登录邮箱查看!");
} else {
alert(data.msg);
}
}
);
}
```

邮箱内容:

```html
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
<link rel="icon" th:href="@{/img/icon.png}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}" />
<link rel="stylesheet" th:href="@{/css/global.css}" />
<link rel="stylesheet" th:href="@{/css/login.css}" />
<title>忘记密码</title>
</head>
<body>
<div class="nk-container">
<!-- 头部 -->
<header class="bg-dark sticky-top" th:replace="index::header">
</header>

<!-- 内容 -->
<div class="main">
<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
<form class="mt-5" th:action="@{/forgetPassword}" method="post">
<div class="form-group row">
<label for="your-email" class="col-sm-2 col-form-label text-right">邮箱:</label>
<div class="col-sm-10">
<input type="email" th:class="|form-control ${emailMsg!=null?'is-invalid':''}|"
th:value="${param.email}"
id="your-email" placeholder="请输入您的邮箱!" name="email" required>
<div class="invalid-feedback" th:text="${emailMsg}">
该邮箱已被注册!
</div>
</div>
</div>
<div class="form-group row mt-4">
<label for="your-password" class="col-sm-2 col-form-label text-right">新密码:</label>
<div class="col-sm-10">
<input type="password" th:class="|form-control ${passwordMsg!=null?'is-invalid':''}|"
th:value="${param.password}"
id="your-password" placeholder="请输入新的密码!" name="password" required>
<div class="invalid-feedback" th:text="${passwordMsg}">
密码长度不能小于8位!
</div>
</div>
</div>
<div class="form-group row mt-4">
<div class="col-sm-2"></div>
<div class="col-sm-10 text-center">
<button type="submit" class="btn btn-info text-white form-control">重置密码</button>
</div>
</div>
</form>
</div>
</div>

<!-- 尾部 -->
<footer class="bg-dark" th:replace="index::footer">
</footer>
</div>

<script th:src="@{/js/jquery-3.1.0.min.js}"></script>
<script type="module" th:src="@{/js/popper.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/js/global.js}"></script>
<div>
<p>
<b th:text="${email}">[email protected]</b>, 您好!
</p>
<p>
您正在找回账号的密码,本次操作的验证码为 <b th:text="${verifyCode}">u5s6dt</b>,请您及时设置新密码!
</p>
</div>
</body>
</html>
```
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -21,10 +22,7 @@
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
Expand Down Expand Up @@ -182,11 +180,35 @@ public String getForgetPage(){
return "/site/forget";
}

// 邮箱验证码
@RequestMapping(path = "/forget/code", method = RequestMethod.GET)
@ResponseBody
public String getForgetCode(String email, HttpSession session) {
Map<String, Object> map = userService.getForgetCode(email);
if (map.containsKey("verifyCode")) {
// 保存验证码,注意这里要对不同的邮箱保存不同的验证码,防止换邮箱后验证码还是之前的
session.setAttribute(email + "_verifyCode", map.get("verifyCode"));
return CommunityUtil.getJSONString(0);
} else {
return CommunityUtil.getJSONString(1, (String) map.get("emailMsg"));
}
}

@RequestMapping(path = "/forgetPassword", method = RequestMethod.POST)
public String updatePassword(String email, String password ,Model model){
public String resetPassword(String email, String verifyCode, String password, Model model, HttpSession session) {
// 检查验证码
String code = (String) session.getAttribute(email + "_verifyCode");
if (StringUtils.isBlank(verifyCode) || StringUtils.isBlank(code) || !code.equalsIgnoreCase(verifyCode)) {
// 验证码错误,返回重置密码页面
model.addAttribute("codeMsg", "验证码错误!");
return "/site/forget";
}

Map<String, Object> map = userService.resetPassword(email, password);
if (map == null || map.isEmpty()) {
return "/site/login";
model.addAttribute("msg", "重置密码成功,正在前往登录页面,请重新登录!");
model.addAttribute("target", "/login");
return "/site/operate-result";
} else {
model.addAttribute("emailMsg", map.get("emailMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/com/nowcoder/community/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,32 @@ public Map<String, Object> resetPassword(String email, String password) {
return map;
}

// 重置密码邮箱验证码:
public Map<String, Object> getForgetCode(String email) {
Map<String, Object> map = new HashMap<>();
if (StringUtils.isBlank(email)) {
map.put("emailMsg", "邮箱不能为空!");
return map;
}
User user = userMapper.selectByEmail(email);
if (user == null) {
map.put("emailMsg", "该邮箱不存在!");
return map;
}
if (user.getStatus() == 0) {
map.put("emailMsg", "该邮箱未激活!");
}
// 发送邮件
Context context = new Context();
context.setVariable("email", email);
String code = CommunityUtil.genUUID().substring(0, 4);
context.setVariable("verifyCode", code);
String content = templateEngine.process("/mail/forget", context);
mailClient.sendMail(email, "找回密码", content);
map.put("verifyCode", code);
return map;
}

// 更新密码 - not forget
public Map<String, Object> updatePassword(int userId, String oldPassword, String newPassword1, String newPassword2){
Map<String, Object> map = new HashMap<>();
Expand Down
25 changes: 25 additions & 0 deletions src/main/resources/static/js/forget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
$(function(){
$("#verifyCodeBtn").click(getVerifyCode);
});

function getVerifyCode() {
var email = $("#your-email").val();

if(!email) {
alert("请先填写您的邮箱!");
return false;
}

$.get(
CONTEXT_PATH + "/forget/code",
{"email":email},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
alert("验证码已发送至您的邮箱,请登录邮箱查看!");
} else {
alert(data.msg);
}
}
);
}
Loading

0 comments on commit 6806ee4

Please sign in to comment.