- 1 访问登陆页面
- 1.1 Conroller
- 1.2 login.html
- 2 登陆
- 2.1 数据访问层
- 2.1.1 login-ticket实体
- 2.1.2 dao层的Mapper接口
- 2.1.3 Mapper对应的xml
- 2.1.4 测试
- 2.2 业务层
- 2.3 视图层
- 2.4 动态页面
- 3 验证码
- 4 退出
- 4.1 业务层
- 4.2 视图层
- 4.3 配置“退出登录”按钮的链接
拆解功能:
1.访问登陆页面:点击上方“登陆”键跳转
2.登陆:验证用户名、密码,
成功就发放登陆凭证给浏览器
失败就返回登陆页面
图:login-ticket表 1 访问登陆页面 1.1 Conroller
//访问登陆页面 @RequestMapping(path = "/login",method = RequestMethod.GET) public String getLogin(){ return "/site/login"; }1.2 login.html
首部复用index的首部,头尾的静态资源改成动态链接
2 登陆数据访问层:提供业务层所需的相应查询方法
业务层:根据用户传入的用户名查找用户u
将用户u的密码与传入的密码经MD5加密后比较,若一致,更新login-ticket,并返回ticket
若不一致,返回错误信息(所以需要针对login-ticket的dao)
视图层:调用业务层,返回相应页面
类名和表名相对应
1.表里有什么字段,实体类里就增加几个属性与之对应
2.get/set方法
3.toString方法
1.注解@Mapper
2.声明增删改查方法
1.头
2.增删改查方法对应的sql语句
2.1.4 测试insert into login_ticket (user_id,ticket,status,expired) values (#{userId},#{ticket},#{status},#{expired}) select id,user_id,ticket,status,expired from login_ticket where ticket = #{ticket} update login_ticket set status = #{status} where ticket = #{ticket}
@Autowired private LoginTicketMapper loginTicketMapper; @Test public void testLoginTicketMapper(){ //测试插入 // LoginTicket loginTicket = new LoginTicket(); // loginTicket.setUserId(1); // loginTicket.setTicket("hello"); // loginTicket.setStatus(0); // loginTicket.setExpired(new Date(System.currentTimeMillis()+60*10*1000)); // // loginTicketMapper.insertLoginTicket(loginTicket); // System.out.println(loginTicket); //测试查询 // String ticket = "hello"; // LoginTicket loginTicket = loginTicketMapper.selectByTicket(ticket); // System.out.println(loginTicket); //测试修改 String ticket = "hello"; loginTicketMapper.updateStatus(ticket, 1); }2.2 业务层
1.空值处理
2.验证用户名 、验证密码、验证是否激活
3.生成登陆凭证
@Autowired private LoginTicketMapper loginTicketMapper; //用户登陆 public Map2.3 视图层login(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 (!user.getPassword().equals(password)) { 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 * 1000)); loginTicketMapper.insertLoginTicket(loginTicket); map.put("ticket", loginTicket.getTicket()); return map; }
@RequestMapping(path = "/login", method = RequestMethod.POST) public String login(String username, String password, String code, boolean rememberme, Model model, HttpServletResponse response) { // 检查账号,密码 int expiredSeconds = rememberme ? REMEMBER_EXPIRED_SEConDS : DEFAULT_EXPIRED_SECONDS; Map2.4 动态页面 3 验证码map = userService.login(username, password, expiredSeconds); if (map.containsKey("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"; } }
验证码这个东西我没有自己实现,老师的思路大概是:
导入kaptcha包,利用kaptcha生成验证码
Controller层,利用kaptcha生成验证码,并将验证码图片发送到页面,将验证码文本存入session
用户点击登陆按钮时的请求中带有session id的cookie,服务器取到session中的验证码,与用户传入的验证码做匹配
问题:验证码是如何刷新的?
controller有一个专门的生成验证码的方法,用户点击刷新验证码,就会转到这个方法
这个方法做了三件事:生成验证码,把验证码文本装入session,把验证码图片传回页面。
这就保证了用户每一次刷新看到的验证码与session存入的验证码一致
@RequestMapping(path = "/kaptcha", method = RequestMethod.GET) public void getKaptcha(HttpServletResponse response) { // 生成验证码 String text = kaptchaProducer.createText(); BufferedImage image = kaptchaProducer.createImage(text); // 将验证码存入session // session.setAttribute("kaptcha", text); //验证码的归属 String kaptchaOwner = CommunityUtil.generateUUID(); cookie cookie = new cookie("kaptchaOwner", kaptchaOwner); cookie.setMaxAge(60); cookie.setPath(contextPath); response.addcookie(cookie); //将验证码存入Redis String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner); redisTemplate.opsForValue().set(redisKey,text,60, TimeUnit.SECONDS); // 将图片输出给浏览器 response.setContentType("image/png"); try { OutputStream os = response.getOutputStream(); ImageIO.write(image, "png", os); } catch (IOException e) { logger.error("响应验证码失败:" + e.getMessage()); } }4 退出
把凭证改为失效
4.1 业务层//用户退出 public void logout(String ticket) { loginTicketMapper.updateStatus(ticket, 1); }4.2 视图层
@RequestMapping(path = "/logout", method = RequestMethod.GET) public String logout(@cookievalue("ticket") String ticket) { userService.logout(ticket); return "redirect:/login"; }4.3 配置“退出登录”按钮的链接
index.html
退出登录
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)