redis(day02-短信登录)

目录

一复习

1知道NoSQL与SQL的差别

[2 熟悉Redis的常用5种数据结构](#2 熟悉Redis的常用5种数据结构)

3熟悉Redis的常用命令

4熟练使用Jedis或SpringDataRedis

二实战篇

[实战篇 - 01.Redis 企业实战课程介绍](#实战篇 - 01.Redis 企业实战课程介绍)

[实战篇 - 02. 短信登录 - 导入黑马点评项目](#实战篇 - 02. 短信登录 - 导入黑马点评项目)

问题:已经有优惠券表了为什么还需要优惠券订单表?

[实战篇 - 03. 短信登录 - 基于 session 实现短信登录的流程](#实战篇 - 03. 短信登录 - 基于 session 实现短信登录的流程)

问题:发送短信验证码(登录/注册/校验)流程?

[实战篇 - 04. 短信登录 - 实现发送短信验证码功能](#实战篇 - 04. 短信登录 - 实现发送短信验证码功能)

问题:将验证码保存到session和redis有什么区别?

问题Lmybatis-plus怎么使用?

问题:为什么下图的同意协议按钮点不动?

[实战篇 - 05. 短信登录 - 实现短信验证码登录和注册功能](#实战篇 - 05. 短信登录 - 实现短信验证码登录和注册功能)

[实战篇 - 06. 短信登录 - 实现登录校验拦截器](#实战篇 - 06. 短信登录 - 实现登录校验拦截器)

问题:preHandle,postHandle,afterCompletion是什么?

问题:为什么使用redis存储令牌后就不需要后置拦截器移除用户了?

[实战篇 - 07. 短信登录 - 隐藏用户敏感信息](#实战篇 - 07. 短信登录 - 隐藏用户敏感信息)

[实战篇 - 08. 短信登录 - session 共享的问题分析](#实战篇 - 08. 短信登录 - session 共享的问题分析)

[实战篇 - 09. 短信登录 - Redis 代替 session 的业务流程](#实战篇 - 09. 短信登录 - Redis 代替 session 的业务流程)

[实战篇 - 10. 短信登录 - 基于 Redis 实现短信登录](#实战篇 - 10. 短信登录 - 基于 Redis 实现短信登录)

问题:解释下面代码?

问题:@Autowired和@Resource有什么区别?

问题:redis中存储的token有效期是基于用户最后访问时间经过30min取消,不是首次登录30min后取消,该怎么动态刷新token的过期时间?

[实战篇 - 11. 短信登录 - 解决状态登录刷新的问题](#实战篇 - 11. 短信登录 - 解决状态登录刷新的问题)

问题:为什么要优化成两个拦截器?

问题:stringRedisTemplate.opsForHash().entries(key)和.get(key)的区别?

[entries 是获取整个哈希表的所有键值对,返回是 Map 集合。](#entries 是获取整个哈希表的所有键值对,返回是 Map 集合。)

[get 是获取哈希表中指定 key 的字段值,返回是单个值。](#get 是获取哈希表中指定 key 的字段值,返回是单个值。)

末尾页:


一复习

1知道NoSQL与SQL的差别

2 熟悉Redis的常用5种数据结构

3熟悉Redis的常用命令

4熟练使用Jedis或SpringDataRedis

二实战篇

实战篇 - 01.Redis 企业实战课程介绍

实战篇 - 02. 短信登录 - 导入黑马点评项目

问题:已经有优惠券表了为什么还需要优惠券订单表?

实战篇 - 03. 短信登录 - 基于 session 实现短信登录的流程

问题:发送短信验证码(登录/注册/校验)流程?

实战篇 - 04. 短信登录 - 实现发送短信验证码功能

问题:将验证码保存到session和redis有什么区别?

  • Session 存内存,Redis 独立缓存
  • Session 不支持集群,Redis 支持分布式
  • Session 过期不灵活,Redis 可精确设置过期
  • Session 重启丢失,Redis 更稳定
  • 生产环境验证码统一用 Redis
java 复制代码
    @Override
    public Result sendCode(String phone, HttpSession session) {
        // 1.校验手机号
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合,返回错误信息
            return Result.fail("手机号格式错误!");
        }
        // 3.符合,生成验证码
        String code = RandomUtil.randomNumbers(6);

        // 4.保存验证码到 session(session.setAttribute("code", code);)
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);

        // 5.发送验证码
        log.debug("发送短信验证码成功,验证码:{}", code);
        // 返回ok
        return Result.ok();
    }

问题Lmybatis-plus怎么使用?

接口层extends IService<实体类>

实现层extends ServiceImpl<mapper类,实体类> implements 接口

到时候就可以直接使用query(),update()这些了

问题:为什么下图的同意协议按钮点不动?

实战篇 - 05. 短信登录 - 实现短信验证码登录和注册功能

java 复制代码
    @Override
    public Result login(LoginFormDTO loginForm, HttpSession session) {
        // 1.校验手机号
        String phone = loginForm.getPhone();
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合,返回错误信息
            return Result.fail("手机号格式错误!");
        }
        // 3.从redis获取验证码并校验
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        String code = loginForm.getCode();
        if (cacheCode == null || !cacheCode.equals(code)) {
            // 不一致,报错
            return Result.fail("验证码错误");
        }

        // 4.一致,根据手机号查询用户 select * from tb_user where phone = ?
        User user = query().eq("phone", phone).one();

        // 5.判断用户是否存在
        if (user == null) {
            // 6.不存在,创建新用户并保存
            user = createUserWithPhone(phone);
        }

        // 7.保存用户信息到 redis中
        // 7.1.随机生成token,作为登录令牌
        String token = UUID.randomUUID().toString(true);
        // 7.2.将User对象转为HashMap存储
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
        // 7.3.存储
        String tokenKey = LOGIN_USER_KEY + token;
        stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
        // 7.4.设置token有效期
        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);

        // 8.返回token
        return Result.ok(token);
    }

实战篇 - 06. 短信登录 - 实现登录校验拦截器

问题:preHandle,postHandle,afterCompletion是什么?

前置拦截器,后置拦截器

  • preHandle:Controller 之前 → 拦截、登录判断
  • postHandle:Controller 之后 → 修改响应
  • afterCompletion:页面渲染完 → 清理资源

问题:为什么使用redis存储令牌后就不需要后置拦截器移除用户了?

因为用户信息存在 Redis 里,而不是存在 ThreadLocal 里了! 你现在这个拦截器根本没往 ThreadLocal 存用户 ,自然就不用删

实战篇 - 07. 短信登录 - 隐藏用户敏感信息

实战篇 - 08. 短信登录 - session 共享的问题分析

实战篇 - 09. 短信登录 - Redis 代替 session 的业务流程

实战篇 - 10. 短信登录 - 基于 Redis 实现短信登录

问题:解释下面代码?

java 复制代码
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
java 复制代码
Map<String, Object> userMap = BeanUtil.beanToMap(
    userDTO,                // 要转换的源对象
    new HashMap<>(),        // 转换后要放进的目标 Map
    CopyOptions.create()    // 转换规则
            .setIgnoreNullValue(true)  // 忽略值为 null 的字段
            .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString())
            // 把所有字段的值 转成 String
);

问题:@Autowired和@Resource有什么区别?

  • @Autowired按类型注入(Spring 核心注解)
  • @Resource按名称注入(JSR-250 标准注解,默认按名称,找不到才按类型)

问题:redis中存储的token有效期是基于用户最后访问时间经过30min取消,不是首次登录30min后取消,该怎么动态刷新token的过期时间?

每次用户访问接口时,都重新把 Redis 里的 token 过期时间设置为 30 分钟 → 这就叫 "滑动过期" 只要用户一直在操作,token 就永远不过期;30 分钟不操作,自动失效


🧠 原理(超级好懂)

  • 首次登录:设置过期 30 分钟
  • 用户每发一次请求重置过期时间为 30 分钟
  • 30 分钟不访问:token 自动过期

这就是你要的:基于最后一次访问时间过期

我们可以在拦截器的位置加一次刷新redis的token过期时间(再加一层拦截器拦截所有,只刷新token过期时间,其他事情不干)

实战篇 - 11. 短信登录 - 解决状态登录刷新的问题

问题:为什么要优化成两个拦截器?

因为一个拦截器的时候只拦截需要登录的路径,那不需要登录的路径不拦截就没办法动态刷新token的有效期了

问题:stringRedisTemplate.opsForHash().entries(key)和.get(key)的区别?

entries 是获取整个哈希表的所有键值对,返回是 Map 集合。

get 是获取哈希表中指定 key 的字段值,返回是单个值。

末尾页:

本文介绍了Redis在企业项目中的实战应用,重点讲解了短信登录功能的实现过程。首先对比了Session和Redis存储验证码的优劣,指出Redis在分布式、稳定性和过期设置方面的优势。然后详细说明了基于Redis的短信验证码登录流程,包括验证码生成、存储、校验以及用户信息保存到Redis等关键步骤。文章还探讨了登录拦截器的实现原理,解释了为何使用Redis后无需后置拦截器处理用户信息。最后针对常见问题如MyBatis-Plus使用、注解区别、Redis数据结构操作等进行了说明,并提出了动态刷新token有效期的解决方案。

相关推荐
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的分片管理(17)
数据库·学习·mongodb
木下~learning2 小时前
MySQL 从入门到精通:安装、终端操作、远程连接与 C 语言 API 全教程
c语言·数据库·mysql
不会写DN2 小时前
如何设计应用层 ACK 来补充 TCP 的不足?
开发语言·网络·数据库·网络协议·tcp/ip·golang
升职佳兴2 小时前
告别套娃式子查询:SQL WITH 语句(CTE)深度实战指南
数据库·sql
却话巴山夜雨时i2 小时前
互联网大厂Java面试:从Spring到微服务的全栈挑战
java·spring boot·redis·微服务·面试·kafka·技术栈
杰克尼2 小时前
springCloud(day10-面试篇)
redis·spring cloud·面试
zzh0812 小时前
PG数据库日常应用
数据库·oracle
阿维的博客日记2 小时前
MySQL中type字段解析
数据库·mysql
Trouvaille ~2 小时前
【MySQL篇】表的操作:数据的容器
linux·数据库·mysql·oracle·xshell·ddl·表的操作