Spring Boot开发登录、退出功能
① 访问登录页面:点击顶部区域内的链接,打开登录页面。② 登录:验证账号、密码、验证码;成功时,生成登录凭证,发送给客户端;失败时,跳转回登录页。③ 退出:将登录凭证修改为失效状态;跳转至网站首页。④ 忘记密码: 点击登录页面上的“忘记密码”链接,打开忘记密码页面;在表单中输入注册的邮箱,点击获取验证码按钮,服务器为该邮箱发送一份验证码;在表单中填写收到的验证码及新密码,点击重置密码,服务器对密码
·
1. 功能描述
① 访问登录页面:点击顶部区域内的链接,打开登录页面。
② 登录:验证账号、密码、验证码;成功时,生成登录凭证,发送给客户端;失败时,跳转回登录页。
③ 退出:将登录凭证修改为失效状态;跳转至网站首页。
④ 忘记密码: 点击登录页面上的“忘记密码”链接,打开忘记密码页面;在表单中输入注册的邮箱,点击获取验证码按钮,服务器为该邮箱发送一份验证码;在表单中填写收到的验证码及新密码,点击重置密码,服务器对密码进行修改。
2. 登录、退出
LoginController.java
@PostMapping("/login")
public String login(String username, String password, String code, boolean rememberme,
Model model, HttpSession session, HttpServletResponse response) {
// 检查验证码
String kaptcha = (String) session.getAttribute("kaptcha");
if (StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equalsIgnoreCase(code)) {
model.addAttribute("codeMsg", "验证码不正确!");
return "/site/login";
}
// 检查账号,密码
int expiredSeconds = rememberme ? REMEMBER_EXPIRED_SECONDS : DEFAULT_EXPIRED_SECONDS;
Map<String, Object> map = userService.login(username, password, expiredSeconds);
if (map.containsKey("ticket")) {
Cookie cookie = new Cookie("ticket", map.get("ticket").toString());
cookie.setPath(contextPath);
cookie.setMaxAge(expiredSeconds);
response.addCookie(cookie);
return "redirect:/index";
} else {
model.addAttribute("usernameMsg", map.get("usernameMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
return "/site/login";
}
}
@GetMapping("/logout")
public String logout(@CookieValue("ticket") String ticket) {
userService.logout(ticket);
return "redirect:/login";
}
UserService.java
public Map<String, Object> login(String username, String password, int expiredSeconds) {
Map<String, Object> map = new HashMap<>();
// 空值处理
if (StringUtils.isBlank(username)) {
map.put("usernameMsg", "账号不能为空!");
return map;
}
if (StringUtils.isBlank(password)) {
map.put("passwordMsg", "密码不能为空!");
return map;
}
// 验证账号
User user = userMapper.selectByName(username);
if (user == null) {
map.put("usernameMsg", "该账号不存在!");
return map;
}
// 验证状态
if (user.getStatus() == 0) {
map.put("usernameMsg", "该账号未激活!");
return map;
}
// 验证密码
password = CommunityUtil.md5(password + user.getSalt());
if (!user.getPassword().equals(password)) {
map.put("passwordMsg", "密码不正确!");
return map;
}
// 生成登录凭证
LoginTicket loginTicket = new LoginTicket();
loginTicket.setUserId(user.getId());
loginTicket.setTicket(CommunityUtil.generateUUID());
loginTicket.setStatus(0);
loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));
loginTicketMapper.insertLoginTicket(loginTicket);
map.put("ticket", loginTicket.getTicket());
return map;
}
public void logout(String ticket) {
loginTicketMapper.updateStatus(ticket, 1);
}
public LoginTicket findLoginTicket(String ticket) {
return loginTicketMapper.selectByTicket(ticket);
}
public int updateHeader(int userId, String headerUrl) {
return userMapper.updateHeader(userId, headerUrl);
}
login.html
<!-- 内容 -->
<div class="main">
<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
<h3 class="text-center text-info border-bottom pb-3">登 录</h3>
<form class="mt-5" method="post" th:action="@{/login}">
<div class="form-group row">
<label for="username" class="col-sm-2 col-form-label text-right">账号:</label>
<div class="col-sm-10">
<input type="text" th:class="|form-control ${usernameMsg!=null?'is-invalid':''}|"
th:value="${param.username}"
id="username" name="username" placeholder="请输入您的账号!" required>
<div class="invalid-feedback" th:text="${usernameMsg}">
该账号不存在!
</div>
</div>
</div>
<div class="form-group row mt-4">
<label for="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="password" name="password" placeholder="请输入您的密码!" required>
<div class="invalid-feedback" th:text="${passwordMsg}">
密码长度不能小于8位!
</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':''}|"
id="verifycode" name="code" placeholder="请输入验证码!">
<div class="invalid-feedback">
验证码不正确!
</div>
</div>
<div class="col-sm-4">
<img th:src="@{/kaptcha}" id="kaptcha" style="width:100px;height:40px;" class="mr-2"/>
<a href="javascript:refresh_kaptcha();" class="font-size-12 align-bottom">刷新验证码</a>
</div>
</div>
<div class="form-group row mt-4">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<input type="checkbox" id="remember-me" name="rememberme"
th:checked="${param.rememberme}">
<label class="form-check-label" for="remember-me">记住我</label>
<a href="forget.html" class="text-danger float-right">忘记密码?</a>
</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>
3. 忘记密码
LoginController.java
@GetMapping("/forget/code")
@ResponseBody
public String getForgetCode(String email, HttpSession session, Model model) {
if (StringUtils.isBlank(email)) {
return CommunityUtil.getJSONString(1, "邮箱不能为空!");
}
Map<String, Object> map = userService.verifyEmail(email);
if(map.containsKey("user")) {//判断是否有邮箱的注册信息
// 保存验证码
session.setAttribute("verifyCode", map.get("code"));
return CommunityUtil.getJSONString(0);
} else {
return CommunityUtil.getJSONString(1, "查询不到该邮箱注册信息");
}
}
@PostMapping("/forget/password")
public String resetPassword(String email, String verifyCode, String password, Model model, HttpSession session) {
String code = (String) session.getAttribute("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.containsKey("user")) {
model.addAttribute("msg","修改密码成功,请重新登录");
model.addAttribute("target","/login");
return "/site/operate-result";
} else {
model.addAttribute("emailMsg", map.get("emailMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
return "/site/forget";
}
}
UserService.java
//重置密码前校验邮箱
public Map<String, Object> verifyEmail(String email) {
Map<String,Object> map = new HashMap<>();
// 空值处理
if (StringUtils.isBlank(email)) {
//不需要写emailMsg,直接返回空的就行
return map;
}
User user = userMapper.selectByEmail(email);
if (user == null) {
//不需要写emailMsg,直接返回空的就行
return map;
} else {
//如果能查到这个邮箱就发送邮件
Context context = new Context();
context.setVariable("email", email);
String code = CommunityUtil.generateUUID().substring(0, 4);
context.setVariable("verifyCode", code);
String content = templateEngine.process("/mail/forget", context);
mailClient.sendMail(email, "找回密码", content);
map.put("code", code);
}
map.put("user", user);
return map;
}
// 重置密码
public Map<String, Object> resetPassword(String email, String password) {
Map<String, Object> map = new HashMap<>();
// 空值处理
if (StringUtils.isBlank(email)) {
map.put("emailMsg", "邮箱不能为空!");
return map;
}
if (StringUtils.isBlank(password)) {
map.put("passwordMsg", "密码不能为空!");
return map;
}
// 验证邮箱
User user = userMapper.selectByEmail(email);
if (user == null) {
map.put("emailMsg", "该邮箱尚未注册!");
return map;
}
// 重置密码
password = CommunityUtil.md5(password + user.getSalt());
userMapper.updatePassword(user.getId(), password);
map.put("user", user);
return map;
}
更多推荐
已为社区贡献1条内容
所有评论(0)