【Java Web】用Redis优化登陆模块

这篇具有很好参考价值的文章主要介绍了【Java Web】用Redis优化登陆模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 使用Redis存储验证码
    • 验证码需要频繁访问和封信,对性能要求高;
    • 验证码不需要永久保存,通常在很短时间内失效;
    • 分布式部署,存在Session共享问题;
  • 使用Redis存储登陆凭证
    • 处理每次请求时,都要查询用户登陆凭证,访问频率非常高;
  • 使用Redis缓存用户信息
    • 处理每次请求时,都要根据凭证查询用户信息,访问频率非常高。
      • 查询缓存中是否有user;
      • 如果没有就初始化缓存;
      • 如果user的信息更新,将清除缓存;

1. 使用Redis存储验证码

  • 在生成验证码的逻辑中,owner由UUID生成,并交给Cookie;然后将验证码text存到kaptcha:owner键中,并设置有效时间为60秒
@RequestMapping(path="/kaptcha", method = RequestMethod.GET)
    public void getKaptcha(HttpServletResponse response, HttpSession session){
        // 生成验证码
        String text = kaptchaProducer.createText();
        BufferedImage image = kaptchaProducer.createImage(text);

        // 将验证码存入session
        // session.setAttribute("kaptcha", text);
        // 优化:存到redis里
        // 验证码的归属owner
        String kaptchaOwner = CommunityUtil.generateUUID();
        Cookie cookie = new Cookie("kaptchaOwner",kaptchaOwner);
        cookie.setMaxAge(60);
        cookie.setPath(context_path);
        response.addCookie(cookie);

        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());
        }
    }
  • 在登陆功能中,键从cookie中去哪出,然后从redis中获取kaptcha:kaptchaOwner键对应的值(验证码),判断验证码是否正确;
@RequestMapping(path = "/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){
        // 从Session中取并检查验证码 --> 优化:从Redis中取
        // String kaptcha = (String) session.getAttribute("kaptcha");
        String kaptcha = null;
        if(StringUtils.isNotBlank(kaptchaOwner)){
            String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
            kaptcha = (String) redisTemplate.opsForValue().get(redisKey);
        }

        if(StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equals(code)){
            model.addAttribute("codeMsg","验证码不正确");
            return "/site/login";
        }
        ......
        ......
        ......
        ......

2. 使用Redis存储登陆凭证

各个逻辑验证通过后,将生成一个用户凭证(UUID生成),存到Redis中,并设置生存周期。在后续需要验证登陆逻辑时,从Redis中get即可。文章来源地址https://www.toymoban.com/news/detail-708930.html

 public Map<String,Object> login(String username, String password, int expiredSeconds){
        Map<String,Object> map = new HashMap<>();
        // 空值判断
        ....
        ....
        
        // 账号密码都不为空,验证合法性
        // 验证账号合法性
        .....
        .....
        
        // 验证密码
        ....
        ....
        
        // 生成登陆凭证
        LoginTicket loginTicket = new LoginTicket();
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(CommunityUtil.generateUUID());
        loginTicket.setStatus(0);
        loginTicket.setExpired(new Date(System.currentTimeMillis() + 1000 * 60 * 10));
        loginTicketMapper.insertLoginTicket(loginTicket);

        String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
        redisTemplate.opsForValue().set(redisKey,loginTicket);

        map.put("ticket", loginTicket.getTicket());
        return map;
    }

3. 使用Redis缓存用户信息

// 1. 优先从缓存中取值
    public User getCache(int userId){
        String redisKey = RedisKeyUtil.getUserKey(userId);
        return (User) redisTemplate.opsForValue().get(redisKey);
    }
    // 2. 如果取不到就初始化缓存
    public User initCache(int userId){
        User user = userMapper.selectById(userId);
        String redisKey = RedisKeyUtil.getUserKey(userId);
        redisTemplate.opsForValue().set(redisKey, user, 3600, TimeUnit.SECONDS);
        return user;
    }

    // 3. 数据变更时清除缓存数据
    public void clearCache(int userId){
        String redisKey = RedisKeyUtil.getUserKey(userId);
        redisTemplate.delete(redisKey);
    }
  • 当获取user的时候,例如根据userId获取用户信息,先判断缓存中查有没有user:userId这个键。如果有,就从缓存中返回User;如果没有,就初始化缓存,将User信息写入user:userId。
  • 每次用户信息修改后,例如更改密码后、退出登录修改ticket后、修改用户激活状态后等,多需要做一次clearCache。

到了这里,关于【Java Web】用Redis优化登陆模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微服务---Redis实用篇-黑马头条项目-优惠卷秒杀功能(使用java阻塞队列对秒杀进行异步优化)

    1.1 秒杀优化-异步秒杀思路 我们来回顾一下下单流程 当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单 4、校验是否是一人一单 5、扣减库存 6、创建订单 在这六

    2024年02月05日
    浏览(50)
  • Java-Web前后端交互实现登陆注册(附源码)

    1.完成用户登录功能。 2.完成注册功能。 3.主体利用Maven导入java中的jar包,使用Servlet实现前后端交互,使用mybatis以及注解,mysql进行数据保存,Tomcat服务器进行开发。 效果图 项目结构 代码 mapper(相对应注解) pojo(实体类) 3.util(工具类) 4.web(Servlet) 1.loginServlet 2.registerServlet

    2023年04月21日
    浏览(30)
  • Redis-使用java代码操作Redis->java连接上redis,java操作redis的常见类型数据存储,redis中的项目应用

    java连接上redis java操作redis的常见类型数据存储 redis中的项目应用 1.java连接上redis 2.java操作redis的常见类型数据存储 3.redis中的项目应用 redis一般用在哪? 存储基本不会变化的数据,然后这些数据又被多个地方使用 redix怎么用 用String 将存储的数据转换成json串,进行存储 在

    2024年02月05日
    浏览(48)
  • 基于redis实现用户登陆

    因为session有数据共享问题,不同tomcat服务器中的session不能共享,之后负载均衡就无法实现。所以我们用redis代替session。redis可以被多个tomcat服务器共享,redis基于内存。 之前的session可以看做登陆凭证,本次登陆凭证由session变为token。 1.用户发送请求携带手机号参数获取验证

    2024年03月12日
    浏览(32)
  • 分布式锁设计选型 不可重入锁建议使用ZooKeeper来实现 可重入锁建议使用Redis来实现 分布式锁:ZooKeeper不可重入锁 Java优化建议

    在设计分布式锁时,需要考虑业务场景和业务需求,以保证锁的正确性和可用性。 例如,在一个电商系统中,每个商品都有一个库存量。为了避免多个用户同时购买同一件商品导致库存出现不一致的情况,可以为每个商品设置一个分布式锁,确保同一时间只能有一个用户购买

    2024年02月08日
    浏览(47)
  • 【Redis】redis入门+java操作redis

    目录 一、Redis入门 1.1 Redis简介 1.2 Redis下载与安装 1.2.1 下载 1.2.2 linux安装 1.2.3 windows安装  1.3  Redis服务启动与停止 1.3.1 linux启动、停止Redis服务 1.3.2 windows启动、停止Redis服务 1.4 修改Redis启动密码 1.4.1 Linux修改设置 1.4.2 windows设置 1.5 修改Redis运行远程连接 1.5.1 linux 1.5.2 window

    2024年02月10日
    浏览(36)
  • 【服务器】Java连接redis及使用Java操作redis、使用场景

    在你的项目里面导入redis的pom依赖 连接redis 以下数据类型基本上涵盖了各种常见的数据存储需求,而且 Redis 的数据类型支持多种高级操作,因此特别适用于 快速、可靠、实时 的数据访问场景。 字符串(String) :最基本的数据类型,可以包含 任何数据 ,包括 二进制数据 。

    2024年02月06日
    浏览(55)
  • 黑马点评-01基于Redis实现短信登陆的功能

    当前模型 nginx服务器的作用 手机或者app端向nginx服务器发起请求,nginx基于七层模型走的是HTTP协议,可以实现基于Lua直接绕开tomcat访问Redis nginx也可以作为静态资源服务器,轻松扛下上万并发并负载均衡到下游的tomcat服务器,利用集群支撑起整个项目 使用nginx部署前端项目后还可以

    2024年02月07日
    浏览(40)
  • 【Redis入门篇】| Redis的Java客户端

    目录 一: Redis的Java客户端 1. Jedis快速入门 2. Jedis连接池 3. SpringDataRedis快速入门 4. RedisSerializer配置 5. StringRedisTemplate 图书推荐 在Redis官网中提供了各种语言的客户端,地址: https://redis.io/resources/clients/ Jedis: 以 Redis 命令作为方法名称,学习成本低,简单实用。但是 Jedis 实

    2024年02月03日
    浏览(98)
  • Redis实战:Redis在Java中的基本使用

    本片将介绍 Redis 在 Java 中的基本使用 1、使用jedis操作redis 1.1、Jedis简介 Jedis 是 Java 语言开发的 Redis 客户端工具包,用于 Java 语言与 Redis 数据进行交互。 Jedis 在 github 官网地址:https://github.com/redis/jedis#readme Jedis 只是对 Redis 命令的封装,掌握 Redis 命令便可轻易上手 Jedis。

    2024年02月10日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包