写在前面:
登录涉及到存放用户信息,应该选择session还是cookie?
@Data
public class LoginTicket {
private int id;
private int userId;
private String ticket;
private int status;
private Date expired;
}
2.Mapper层
@Mapper
public interface LoginTicketMapper {
//插入状态
@Insert({
"insert into login_ticket(user_id,ticket,status,expired)",
"value(#{userId},#{ticket},#{status},#{expired})"
})
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertLoginTicket(LoginTicket loginTicket);
//查询状态
@Select({
"select id,user_id,ticket,status,expired",
"from login_ticket",
"where ticket = #{ticket}"
})
LoginTicket selectByTicket(String ticket);
//更新状态
@Update({
"update login_ticket",
"set status = #{status}",
"where ticket = #{ticket}"
})
int updateStatus(@Param("ticket") String ticket, @Param("status") int status);
}
3.实现登录逻辑(Service层)
public Maplogin(String username, String password, int expiredSeconds) { Map 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 (!password.equals(user.getPassword())) { 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 * 1000L)); loginTicketMapper.insertLoginTicket(loginTicket); map.put("ticket", loginTicket.getTicket()); return map; }
ps:loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000L));
此处要将Integer转化为Long,存储单位为秒,Integer长度显然不足
expiredSeconds参数用来接收用户选择此次登录时长以及cookie存在时长,如:
并设置常数接口;
int EXPIRED_SECOND_DEFAULT = 60 * 60 * 12; int EXPIRED_SECOND_REMEMBER = 60 * 60 * 24 * 100;4.与前端交互(Controller)
@PostMapping("/login")
public String login(String username, String password, String code, Model model, HttpSession session, boolean rememberMe, HttpServletResponse respones) {
//验证码为空
if (code == null || StringUtils.isBlank(code)) {
model.addAttribute("codeMsg", "请填写验证码!");
return "/site/login";
}
//验证码错误
String kaptcha = (String) session.getAttribute("kaptcha");
if (StringUtils.isBlank(kaptcha) || !kaptcha.equalsIgnoreCase(code)) {
model.addAttribute("codeMsg", "验证码填写错误!");
return "/site/login";
}
//检查账号密码
int expiredSecond = rememberMe ? EXPIRED_SECOND_REMEMBER : EXPIRED_SECOND_DEFAULT;
Map map = userService.login(username, password, expiredSecond);
if (map.containsKey("ticket")) {
cookie cookie = new cookie("ticket", map.get("ticket").toString());
//获得该cookie的范围
cookie.setPath(contextPath);
cookie.setMaxAge(expiredSecond);
respones.addcookie(cookie);
return "redirect:/index";
} else {
model.addAttribute("usernameMsg", map.get("usernameMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
return "/site/login";
}
}
账号密码交由服务层判断,验证码信息在controller层判断即可(如何使用springboot实现验证码?)
thymeleaf模板保存数据(防止登录错误信息需要全部重新输入)使用:thymeleaf会自动从当前model中查询该字段 查看是否登录网页浏览cookie信息(F12→Application→cookie)数据库查看 5.退出功能实现
//service层
@Override
public void logout(String ticket) {
loginTicketMapper.updateStatus(ticket,1);
}
//controller层
@GetMapping("/logout")
public String logout (@cookievalue("ticket") String ticket){
userService.logout(ticket);
return "redirect:/login";
}
通过查看数据库确认是否该次登陆已退出



