1.登录
1.1验证账号、密码、验证码
1.2成功时,生成登录凭证,发给客户端
1.3失败时,跳转回登陆页面
1)新建登录凭证表
CREATE TABLE `login_ticket` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `ticket` varchar(45) NOT NULL, `status` int(11) DEFAULT '0' COMMENT '0-有效; 1-无效;', `expired` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `index_ticket` (`ticket`(20)) ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8
2)新建ticket实体类,包含相应字段
public class LoginTicket { private int id; private int userId; private String ticket; private int status; private Date expired; }
3)完善Mapper
@Mapper @Deprecated public interface LoginTicketMapper { @Insert({ "insert into login_ticket (user_id,ticket,status,expired) ", "values (#{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); }
4)Service层login方法
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 u = userMapper.selectByName(username); if (u == null) { map.put("usernameMsg", "用户名不存在!"); return map; } if (u.getStatus() == 0) { map.put("usernameMsg", "该账号未激活!"); return map; } password = CommunityUtil.md5(password + u.getSalt()); if (!u.getPassword().equals(password)) { map.put("passwordMsg", "密码不正确!"); return map; } //生成登录凭证 LoginTicket loginTicket = new LoginTicket(); loginTicket.setUserId(u.getId()); loginTicket.setTicket(CommunityUtil.generateUUID()); loginTicket.setStatus(0); loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000)); //Ed--1.0,没使用Redis作为缓存 // loginTicketMapper.insertLoginTicket(loginTicket); //Ed--2.0使用Redis作为缓存 String ticketKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket()); redisTemplate.opsForValue().set(ticketKey, loginTicket); map.put("ticket", loginTicket.getTicket()); return map; }
5)登录controller
@RequestMapping(value = "/login", method = RequestMethod.POST) public String login(String username, String password, String code, boolean rememberme, Model model, HttpSession session, HttpServletResponse response, @CookieValue("kaptchaOwner") String kaptchaOwner) { //检查验证码 // String kaptcha = (String) session.getAttribute("kaptcha"); String kaptcha = null; if (StringUtils.isNotBlank(kaptchaOwner)) { String kaptchaKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner); kaptcha = (String) redisTemplate.opsForValue().get(kaptchaKey); } if (StringUtils.isBlank(code) || StringUtils.isBlank(kaptcha) || !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 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"; } }
2.退出
2.1将登录凭证修改为失效状态
@RequestMapping(value = "/logout", method = RequestMethod.GET) public String logout(@CookieValue("ticket") String ticket) { userService.logout(ticket); SecurityContextHolder.clearContext(); return "redirect:/login"; }