问答社区-开发登录、退出功能
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";
}
