项目开发日志——登录与退出
访问登录页面
点击页面上方的登录标签,跳转到登录页面。
只需要在Controller层实现跳转逻辑,然后编写HTML的页面。
@RequestMapping(path = "/login", method = RequestMethod.GET)
public String getLoginPage() {
return "/site/login";
}
index.html部分如下:
<header>
<a class="nav-link" th:href="@{/login}">登录</a>
</header>
登录业务逻辑
1. 验证账号、密码、验证码
在Service层处理login业务逻辑,需要Controller传入三个参数,用户名、密码和登录凭证的持续时间
然后将业务处理结果以map集合的形式返回给Controller层
public Map<String, Object> login(String username, String password,int expiredSeconds){
//因为处理结果情况较多,所以可以考虑用map来返回
Map<String,Object> map = new HashMap<>();
// 空值处理
if (StringUtils.isEmpty(username)) {
map.put("usernameMsg", "账号不能为空!");
return map;
}
if (StringUtils.isEmpty(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 = MooclubUtil.md5(password + user.getSalt());
if (!user.getPassword().equals(password)) {
map.put("passwordMsg", "密码不正确!");
return map;
}
// 生成登录凭证
LoginTicket loginTicket = new LoginTicket();
loginTicket.setUserId(user.getId());
loginTicket.setTicket(MooclubUtil.generateUUID());
loginTicket.setStatus(0);
loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));
loginTicketMapper.insertLoginTicket(loginTicket);
//登录凭证放入map集合,代表成功登录
map.put("ticket", loginTicket.getTicket());
return map;
}
2. 跳转页面
Controller层来接收客户端传来的参数,并调用Service层的login()方法来处理。
如果service返回的数据有ticket,说明登陆成功,重定向到首页
如果返回的数据没有ticket,说明有错误,返回到登录页面并将错误信息返回
//用户登录
@RequestMapping(path = "/login", method = RequestMethod.POST)
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 experiedSeconds = rememberme ? REMEMBER_EXPIRED_SECONDS : DEFAULT_EXPIRED_SECONDS;
//检查账号密码
Map<String, Object> map = userService.login(username,password,experiedSeconds);
//map集合有ticket键,说明成功,否则失败
if (map.containsKey("ticket")) {
Cookie cookie = new Cookie("ticket",map.get("ticket").toString());
cookie.setPath("contextPath");
cookie.setMaxAge(experiedSeconds);
response.addCookie(cookie);
return "redirect:/index";
}else {
model.addAttribute("usernameMsg",map.get("usernameMsg"));
model.addAttribute("passwordMsg",map.get("passwordMsg"));
return "/site/login";
}
}
login.html部分代码如下:
<body>
<h3 class="text-center">登录</h3>
<form 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 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}" />
</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" th:text="${codeMsg}" />
</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-14 align-bottom">刷新验证码</a>
</div>
</div>
<div class="form-group row mt-4">
<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-10 text-center">
<button type="submit" class="btn btn-info text-white form-control">立即登录</button>
</div>
</div>
</form>
</body>
退出业务处理
退出就将登录凭证中的状态修改为1,代表失效,并跳转到登录页面。
修改登录凭证的状态在UserService中处理,调用loginTicketMapper的updateStatus方法修改登录凭证的状态。
//退出登录
public void logout(String ticket) {
loginTicketMapper.updateStatus(ticket,1);
}
Controller层
@CookieValue注解用来获取cookie中的值
@RequestMapping(path = "/logout", method = RequestMethod.GET)
public String logout(@CookieValue("ticket") String ticket) {
userService.logout(ticket);
return "redirect:/login"; //重定向默认get请求
}
index.html部分代码
<a class="text-center" th:href="@{/logout}">退出登录</a>

浙公网安备 33010602011771号