Redis优化模块(存储验证码、存储登录凭证、缓存用户信息)

一、使用Redis存储验证码

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

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

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

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

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

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

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

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

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

二、使用Redis存储登录凭证

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

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

// 生成登录凭证
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);

String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
redisTemplate.opsForValue().set(redisKey, loginTicket);// loginTicket会自动序列化为String类型

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

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

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

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

 三、使用Redis缓存用户信息

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

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

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

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

private 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. 数据变更时,清除缓存数据

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

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

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

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

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

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

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,针对你的问题,我给出以下的解答: 首先,需要在pom.xml文件中添加redis和spring-boot-starter-data-redis的依赖: ```xml <dependencies> <!-- redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> </dependencies> ``` 接着,我们需要在配置文件中配置redis的连接信息,比如redis的地址、端口、密码等,可以在application.properties或application.yml中进行配置: ```yml spring: redis: host: localhost port: 6379 password: yourpassword ``` 在Java代码中,我们可以使用Spring提供的RedisTemplate来进行redis的操作,比如设置键对、获取键对等。在用户登录的场景中,我们可以将用户信息作为一个JSON字符串存储redis中,键可以使用用户的token或者其他唯一标识符,代码如下: ```java @Autowired private RedisTemplate<String, String> redisTemplate; public void storeUserInfo(String token, User user) { String key = "user:" + token; String value = JSON.toJSONString(user); redisTemplate.opsForValue().set(key, value, 24, TimeUnit.HOURS); // 设置过期时间为24小时 } ``` 在获取用户信息时,我们可以根据token去redis中获取对应的JSON字符串,然后将其转换为User对象,代码如下: ```java public User getUserInfo(String token) { String key = "user:" + token; String value = redisTemplate.opsForValue().get(key); if (value != null) { return JSON.parseObject(value, User.class); } return null; } ``` 以上就是基于Spring Boot和Redis实现用户登录存储用户信息Redis的一个简单示例。当然,在实际应用中,还需要考虑一些问题,比如用户登录的并发性、过期时间的设置、缓存击穿等等,需要根据实际情况进行优化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李巴巴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值