登录
逻辑:
1.ticketmapper写查询ticket表的基本逻辑
@Mapper
public interface LoginTicketMapper {
//每一行字符串最后最好都有空格,引用 #{}
@Insert({
"insert into login_ticket(user_id,ticket,status,expired) ",
"values(#{userId},#{ticket},#{status},#{expired})"
})
@Options(useGeneratedKeys = true,keyProperty = "id") //是否自动生成主键,给的是"id"
int insertLoginTicket(LoginTicket loginTicket);
//查询ticket
@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(String ticket,int status);
}
2.service层调用,依旧是把各种情况封装在一个map中,返回给controller加以判断
//实现登陆的功能
//和注册类似,返回一个map涵盖多种情况
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","该账号未激活");
}
//验证密码,先把传入的密码加密
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);//有效的状态,1代表无效登陆
loginTicket.setExpired(new Date(System.currentTimeMillis()+expiredSeconds*1000));
loginTicketMapper.insertLoginTicket(loginTicket);
//要把凭证发给客户端,页面需要记住loginTicket.setTicket(CommunityUtil.generateUUID());这个登陆凭证,下次进来要去找ticket,才能说明登陆成功
//这里类似session
map.put("ticket",loginTicket.getTicket());
return map;
}
3.controller层调用service层
//传进来的是账号密码验证码,这里处理表单提交的数据,用post,那么两个同路径的方法可以区别开来
//要放session和创建cookie 所以需要这么多的参数
@RequestMapping(path = "/login",method = RequestMethod.POST)
public String login(String username,String password,
String code,boolean rememberme,Model model,
HttpSession session,HttpServletResponse response){
//判断验证码,从session中取
String kapthca = (String)session.getAttribute("kaptcha");
// System.out.println(kapthca);
if (StringUtils.isBlank(kapthca) || StringUtils.isBlank(code) || !kapthca.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")){
//成功了,因为service层只有成功了才放ticket
//要把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";
}
}
3.最后在前端页面中调用controller层中model的各种msg(提交表单后会自动把前端里面命名的属性装配到controller中)。
退出
1.DAO层写好更改状态的方法了
2.在service层中直接调用
public void logout(String ticket){
loginTicketMapper.updateStatus(ticket,1);//1代表退出,登录无效
}
3.controller层
@RequestMapping(path = "/logout",method = RequestMethod.GET)
//把客户端cookie中的数据给spring管理
public String logout(@CookieValue("ticket") String ticket){
userService.logout(ticket);
return "redirect:/login";
}
4.前端绑定logout的地址