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有效期的解决方案。

相关推荐
小二·15 小时前
PostgreSQL 高级特性与性能调优
数据库·postgresql
正经教主15 小时前
【docker基础】Redis的docker部署
redis·docker·容器
努力成为AK大王15 小时前
计算机底层核心原理:CPU、总线、缓存与内存深度解析
缓存·内存·cpu
风味蘑菇干15 小时前
JDBC(数据库连接池&DBUtils)
java·数据库
标书畅畅行15 小时前
深度解析钛投标AI标书工具:全流程企业级AI投标解决方案,重构投标数字化生产力
大数据·数据库·人工智能
Wait....15 小时前
MySQL底层知识总结
数据库·mysql
闪电悠米15 小时前
黑马点评-Redis 消息队列-04_stream_seckill_order
数据库·redis·分布式·缓存·oracle·junit·lua
成为你的宁宁15 小时前
【基于 Prometheus Operator 实现 K8s 环境下 Redis Cluster 集群监控部署】
redis·kubernetes·prometheus
SeaTunnel15 小时前
87 个 PR 迭代复盘|Apache SeaTunnel 5 月版本重点更新解读
大数据·数据库·开源·apache·seatunnel
DolphinScheduler社区16 小时前
实战演示 | 基于 Apache DolphinScheduler 与 Apache SeaTunnel 实现 MySQL 到 Doris 离线定时增量同步
数据库·mysql·开源·apache·海豚调度·大数据工作流调度