【SpringBoot仿牛客网】03、开发登陆、退出功能

【SpringBoot仿牛客网】03、开发登陆、退出功能,第1张

【SpringBoot仿牛客网】03、开发登陆、退出功能

文章目录
  • 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)
视图层:调用业务层,返回相应页面

2.1 数据访问层 2.1.1 login-ticket实体

类名和表名相对应
1.表里有什么字段,实体类里就增加几个属性与之对应
2.get/set方法
3.toString方法

2.1.2 dao层的Mapper接口

1.注解@Mapper
2.声明增删改查方法

2.1.3 Mapper对应的xml

1.头






2.增删改查方法对应的sql语句


        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}

    
2.1.4 测试
@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 Map 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;
    }
2.3 视图层
@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;
        Map 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";
        }
    }
2.4 动态页面 3 验证码

验证码这个东西我没有自己实现,老师的思路大概是:
导入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

退出登录

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5582248.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存