Redis使用场景之——限制验证码发送次数

项目中需要一个发送短信验证码的功能,但是需要限制每天发送限制码的次数,可以借助Redis的incr命令实现。

incr命令:

对存储在指定key的数值执行原子的加1操作。

如果指定的key不存在,那么在执行incr操作之前,会先将它的值设定为0

返回值是执行递增操作后key对应的值。

代码:

 long count = redisTemplate.opsForValue().increment(mobile.concat(RedisKeyConstant.SMS_COUNT),1);
if (count > 5 ) {
      throw new ServiceException("您的操作太过频繁!");
} else {
      // 验证码次数凌晨清除
       Duration duration = Duration.between(LocalDateTime.now(), LocalDate.now().plusDays(1).atTime(0,0,0));
          redisTemplate.expire(mobile.concat(RedisKeyConstant.SMS_COUNT),duration.toMinutes(),TimeUnit.MINUTES);
 }

由于Redis是串行执行的,所以increment会每次给key值的value加1,超过5次就抛出异常,提示操作频繁,否则就放过并设置有效时间到第二天凌晨。

### Sa-Token集成Redis使用教程 #### 一、什么是Sa-Token? Sa-Token 是一款用于Java Web项目的鉴权框架,具有轻量级、高性能的特点。它不仅支持传统的Session模式,还提供了基于Token的身份认证方式[^1]。 #### 二、为何要集成Redis客户端(如Redisson) 通过引入Redis作为缓存层,可以有效减轻服务器压力并提高系统的并发处理能力。具体来说,在高并发场景下,利用Redis存储token信息能够显著提升查询效率和响应速度。此外,借助于像Redisson这样的高级客户端库,还可以更方便地操作分布式环境下的数据结构。 #### 三、Maven依赖配置 为了使项目能顺利接入Sa-Token与Redis的支持,需在`pom.xml`文件中加入如下依赖项: ```xml <!-- sa-token 权限认证 --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>x.x.x</version> </dependency> <!-- redisson 连接池 --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>y.y.y</version> </dependency> ``` 请注意替换上述代码中的版本号为最新稳定版。 #### 四、application.yml配置示例 接下来是在Spring Boot应用的配置文件里设置必要的参数来启用这两者的协作工作: ```yaml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true username: root password: 123456 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置 Redis 数据源 redis: host: localhost port: 6379 lettuce: pool: max-active: 8 max-wait: -1ms # 配置 sa-token 相关属性 sa-token: token-name: satoken # 自定义 Token 名称,默认为 `satoken` timeout: 2592000 # token有效期 默认30天(单位:s) is-concurrent: false # 是否开启 并发登录控制 (默认关闭) kickout-rule: FIFOUT # 当达到最大会话数时踢出策略:LIFO/FIFOUT/NO_KICKOUT activity-timeout: 1800 # 单位秒, 用户活动超时时长, 若在此期间无任何请求则自动登出 disable-url-patterns: /login,/logout # 不需要拦截的url路径 ``` 以上配置涵盖了连接到本地MySQL数据库的信息以及针对Redis服务端口等基本信息设定,并指定了关于Sa-Token的一些行为特性调整选项。 #### 五、过滤器配置 为了让每次HTTP请求都能经过身份验证环节,可以在Web应用程序启动类上添加全局异常处理器的同时也注册一个自定义的安全过滤链。下面是一个简单的例子展示如何做到这一点: ```java @Configuration public class SecurityConfig { @Bean public FilterRegistrationBean<SaServletFilter> getSaServletFilter() { // 创建过滤器实例 SaServletFilter filter = new SaServletFilter(); // 设置哪些URL不需要进行权限校验 filter.setExcludeUrlPatterns( "/login", // 登录接口放行 "/register", // 注册接口放行 "/error" // 错误页面放行 ); // 将此过滤器应用于所有请求之前执行 FilterRegistrationBean<SaServletFilter> registration = new FilterRegistrationBean<>(filter); registration.addUrlPatterns("/*"); return registration; } } ``` 这段程序片段的作用在于确保除了指定几个公开访问地址外的所有其他API都需要先完成合法性的检验才能继续向下一层转发处理逻辑。 #### 六、验证机制概述 当涉及到实际业务功能开发阶段时——比如实现用户注册流程,就需要考虑怎样安全可靠地保存新创建账户的相关凭证资料至持久化介质之中去。这里给出了一段简化后的控制器方法用来演示这一过程的关键部分: ```java @PostMapping("/regist") public Boolean regist(@RequestParam String userName,@RequestParam String verCode) throws Exception{ if(StringUtils.isEmpty(userName)||StringUtils.isEmpty(verCode)){ throw new RuntimeException("请输入用户名或验证码!"); } // 查询数据库检查该用户名是否已被占用; User user = userService.findByUsername(username); if(user != null){ throw new RuntimeException("该用户名已存在!"); } // 调用上面提到过的校验用户验证码的方法; boolean checkResult = verifyService.checkVercodeForRegist(phoneNumber,verCode); if(!checkResult){ throw new RuntimeException("验证码错误!"); } // 插入新的用户记录进入数据库表单内,从而获得唯一标识符即userId; Long userId = userService.saveUser(new UserInfoDTO().setUserName(userName)); // 执行登录动作并将产生的token返回给前端设备携带; StpUtil.login(userId); return true; } ``` 在这段伪代码里面可以看到对于输入参数做了初步非空判断之后紧接着就是一系列围绕着账号合法性确认的操作步骤,最后一步则是调用了来自StpUtils工具包所提供的便捷函数完成了整个注册加首次登陆的过程[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值