当前位置:   article > 正文

Redis优化模块(存储验证码、存储登录凭证、缓存用户信息)_验证码用redis缓存存key值给什么

验证码用redis缓存存key值给什么

一、使用Redis存储验证码

  • 验证码需要频繁地访问与刷新,对性能要求较高
  • 验证码不需要永久保存,通常在很短的时间内就会失效
  • 分布式部署时,存在Session共享的问题

以登录模块验证码(一分钟失效)为例:

1. 在登录之前,需要有一个凭证来短暂地映射该用户,对此,我们随机生成一个字符串来作为Redis的key,并将其存入cookie中以便登录时获取

  1. // 验证码的归属
  2. String kaptchaOwner = CommunityUtil.generateUUID();// 自定义的获取随机字符串的方法
  3. Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner);
  4. cookie.setMaxAge(60);// 验证码失效时间1分钟
  5. cookie.setPath(contextPath);// contextPath为项目路径
  6. response.addCookie(cookie);

2. 然后,将验证码存入Redis中(随机生成的字符串作为Redis的key)

  1. // 将验证码存入Redis
  2. String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);// RedisKeyUtil为自定义的获取/拼装Redis Key的一个类
  3. redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);// text为随机验证码

3. 登录时,获取之前存入Redis的验证码

可以通过@CookieValue注解获取之前存入Cookie中的凭证(随机字符串)

@CookieValue("kaptchaOwner") String kaptchaOwner
  1. // 检查验证码
  2. String kaptcha = null;
  3. if(StringUtils.isNoneBlank(kaptchaOwner)){
  4. String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
  5. kaptcha = (String) redisTemplate.opsForValue().get(redisKey);
  6. }

二、使用Redis存储登录凭证

  • 处理每次请求时,都要查询用户的登录凭证,访问的频率非常高

1. 登录时,生成登录凭证,并以登录凭证(随机字符串)作为Redis的Key存入Redis

  1. // 生成登录凭证
  2. LoginTicket loginTicket = new LoginTicket();
  3. loginTicket.setUserId(user.getId());
  4. loginTicket.setTicket(CommunityUtil.generateUUID());
  5. loginTicket.setStatus(0);
  6. loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));
  7. // loginTicketMapper.insertLoginTicket(loginTicket);
  8. String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
  9. redisTemplate.opsForValue().set(redisKey, loginTicket);// loginTicket会自动序列化为String类型

2. 退出登录时,将登录状态改为1,即登录凭证失效

  1. // loginTicketMapper.updateStatus(ticket,1);
  2. String redisKey = RedisKeyUtil.getTicketKey(ticket);
  3. LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);
  4. loginTicket.setStatus(1);
  5. redisTemplate.opsForValue().set(redisKey, loginTicket);

3. 在拦截器的作用下,每次刷新页面,查询登录凭证

  1. // return loginTicketMapper.selectByTicket(ticket);
  2. String redisKey = RedisKeyUtil.getTicketKey(ticket);
  3. return (LoginTicket) redisTemplate.opsForValue().get(redisKey);

 三、使用Redis缓存用户信息

  • 处理每次请求时,都要根据凭证查询用户信息,访问的频率非常高。

1. 每次访问user信息时,优先从缓存中取值

  1. private User getCache(int userId) {
  2. String redisKey = RedisKeyUtil.getUserKey(userId);
  3. return (User) redisTemplate.opsForValue().get(redisKey);
  4. }

2. 从缓存中取不到时,初始化缓存数据(从Mysql中取)

  1. private User initCache(int userId) {
  2. User user = userMapper.selectById(userId);
  3. String redisKey = RedisKeyUtil.getUserKey(userId);
  4. redisTemplate.opsForValue().set(redisKey, user, 3600, TimeUnit.SECONDS);
  5. return user;
  6. }

3. 数据变更时,清除缓存数据

  1. private void clearCache(int userId) {
  2. String redisKey = RedisKeyUtil.getUserKey(userId);
  3. redisTemplate.delete(redisKey);
  4. }

注:数据变更时,若选择修改缓存中的数据,可能会引起并发等问题,所以,我们直接选择删除缓存中的数据,当再次访问此数据时初始化缓存即可。 

从Redis缓存中取用户信息示例:

  1. public User findUserById(int id){
  2. User user = getCache(id);// 先从缓存中取值
  3. if(user == null) {
  4. user = initCache(id);// 取不到时,初始化缓存数据
  5. }
  6. return user;
  7. }

数据变更清除缓存数据示例:

  1. public int updateHeader(int userId,String headerUrl){
  2. int rows = userMapper.updateHeader(userId, headerUrl);// 更改用户信息
  3. clearCache(userId);// 更改用户信息后清除缓存数据
  4. return rows;
  5. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/581363
推荐阅读
相关标签
  

闽ICP备14008679号