Java防止短信盗刷和轰炸的解决方案

 更新时间:2024年02月06日 08:51:37   作者:Java中文社群  
短信盗刷和短信轰炸是项目开发中必须要解决的问题之一,它的优先级不亚于 SQL 注入的问题,今天我们就来看下,如何防止这个问题,需要的朋友可以参考下

1.概念介绍

短信盗刷和短信轰炸的概念如下:

  • 短信盗刷是指使用某种技术手段,伪造大量手机号调用业务系统,盗取并发送大量短信的问题。这样会导致短信系统欠费,不能正常发送短信,同时也给业务系统方,带来了一定的经济损失和不必要的麻烦。
  • 短信轰炸是指攻击者利用某种技术手段,连续、大量地向目标手机号码发送短信,以达到骚扰、干扰或消耗目标用户的时间、流量与精力的目的。这种行为可能会对受害者造成骚扰、通信中断和手机电量消耗过快等问题。

2.解决方案

短信盗刷和短信轰炸属于一类问题,可以一起解决。但这类问题的解决,不能依靠某一种解决方案,而是多种解决方案共同作用,来预防此类问题的发生。

这类问题的综合解决方案有以下几个:

  • 添加图形验证码:用户发送短信前,需要先输入正确的图形验证码,或拖动验证码等验证,验证通过之后,才能正常发送短信验证码。因为图形验证码的破解难度非常大,所以就避免了自动发送短信程序的执行。
  • 添加 IP 限制:对请求 IP 的发送次数进行限制,避免短信盗刷和短信轰炸的问题。例如,每个 IP 每天只能发送 10 条短信。
  • 开启 IP 黑名单:限制某个 IP 短信发送功能,从而禁止自动发送短信程序的执行。
  • 限制发送频次:一个手机号不能一直不停的发送验证码(即使更换了多个 IP 也不行),设置一个手机号,每分钟内只能发送 1 次验证码;一小时之内,只能发送 5 次验证码;一天之内,只能发送 10 次验证码。
  • 开启短信提供商的防控和报警功能:几乎所有的短信提供商都提供了,异常短信的防控和提醒功能,开启这些保护措施,可以尽可能的避免短信盗刷的问题。

具体实现如下。

3.具体解决方案

3.1 添加图形验证码

图形验证码的执行流程如下:

  • 当用户点击“发送短信验证码”的时候,前端程序请求后端生成图形验证码,后端程序生成图形验证码的功能,可以借助 Hutool 框架来生成,它的核心实现代码如下:
@RequestMapping("/getcaptcha")
public AjaxResult getCaptcha(){
    // 1.生成验证码到本地
    // 定义图形验证码的长和宽
    LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(128, 50);
    String uuid = UUID.randomUUID().toString().replace("-","");
    // 图形验证码写出,可以写出到文件,也可以写出到流
    lineCaptcha.write(imagepath+uuid+".png");
    // url 地址
    String url = "/image/"+uuid+".png";
    // 将验证码存储到 redis
    redisTemplate.opsForValue().set(uuid,lineCaptcha.getCode());
    HashMap<String,String> result = new HashMap<>();
    result.put("codeurl",url);
    result.put("codekey",uuid);
    return AjaxResult.succ(result);
}

上述执行代码中有两个关键操作:第一,生成图形验证码,并返回给前端程序;第二,将此图形验证的标识(ID)和正确的验证码保存到 Redis,方便后续验证。

  • 前端用户拿到图形验证码之后,输入图形验证码,请求后端程序验证,并发送短信验证码。
  • 后端程序拿到(图形)验证码之后,先验证(图形)验证码的正确性.如果正确,则发送短信验证码,否则,将不执行后续流程并返回执行失败给前端,核心实现代码如下:
// redis 里面 key 对应的真实的验证码
String redisCodeValue = (String) redisTemplate.opsForValue().get(user.getCodeKey());
// 验证 redis 中的验证码和用户输入的验证码是否一致
if (!StringUtils.hasLength(redisCodeValue) || !redisCodeValue.equals(user.getCheckCode())) {
    // 验证码不正确
    return AjaxResult.fail(-1, "验证码错误");
}
// 清除 redis 中的验证码
redisTemplate.opsForValue().set(userInfoVO.getCodeKey(), "");
// 请求短信 API 发送短信业务......

3.2 添加 IP 限制

IP 限制可以在网关层 Spring Cloud Gateway 中实现,在 Gateway 中使用全局过滤器来完成 IP 限制,核心实现代码如下:

@Component
public class IpFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求 IP
        String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        Long count = redisTemplate.opsForValue().increment(ip, 1); // 累加值
        if(count >= 20){ // 大于最大执行次数
            redisTemplate.opsForValue().decrement(ip, 1); // 变回原来的值
            // 终止执行
            response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
            return response.setComplete();
        }
        redisTemplate.expire(ip, 1, TimeUnit.DAYS); // 设置过期时间
        // 执行成功,继续执行后续流程
        return chain.filter(exchange);
    }
}

其中,访问次数使用 Redis 来存储。

3.3 开启 IP 黑名单

IP 黑名单可以在网管层面通过代码实现,也可以通过短信提供商提供的 IP 黑名单来实现。

例如,阿里云短信提供的 IP 黑名单机制,如下图所示:

通过以上设置之后,我们就可以将监控中有问题的 IP 设置为黑名单,此时 IP 黑名单中的 IP 就不能调用短信的发送功能了。

PS:网关层面实现 IP 黑名单,可以参考添加 IP 限制的代码进行改造。

3.4 限制验证码的发送频次

验证码的发送频次,可以通过网关或短信提供商来解决。以阿里云短信为例,它可以针对每个手机号设置每分钟、每小时、每天的短信最大发送数,如下图所示:

当然,这个值也可以人为修改,但阿里云短信每天单个手机号最多支持发送 40 条短信。

3.5 开启短信提供商的防控和报警功能

短信提供商通常会提供防盗、防刷的机制。例如,阿里短信它可以设置短信发送总量阈值报警、套餐余量提醒、每日/每月发送短信数量限制等功能,如下图所示:

最后

以上就是Java防止短信盗刷和轰炸的解决方案的详细内容,更多关于Java防止短信盗刷和轰炸的资料请关注脚本之家其它相关文章!

相关文章

  • Java实现Consul/Nacos根据GPU型号、显存余量执行负载均衡的步骤详解

    Java实现Consul/Nacos根据GPU型号、显存余量执行负载均衡的步骤详解

    这篇文章主要介绍了Java实现Consul/Nacos根据GPU型号、显存余量执行负载均衡的步骤详解,本文分步骤结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2025-04-04
  • Spring.Net IOC依赖注入原理流程解析

    Spring.Net IOC依赖注入原理流程解析

    这篇文章主要介绍了Spring.Net IOC依赖注入原理流程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Python安装Jupyter Notebook配置使用教程详解

    Python安装Jupyter Notebook配置使用教程详解

    这篇文章主要介绍了Python安装Jupyter Notebook配置使用教程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • SpringBoot向resources下写文件的两种方式

    SpringBoot向resources下写文件的两种方式

    这篇文章给大家分享了两种SpringBoot向resources下写文件的方式,每种方式都有详细的代码示例,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-08-08
  • 使用IDEA进行安卓开发的详细图文教程

    使用IDEA进行安卓开发的详细图文教程

    安卓开发本身就是Java开发的一个分支,我们要确保计算机已经安装好JDK并做好了相关的配置,下面这篇文章主要给大家介绍了关于如何使用IDEA进行安卓开发的详细图文教程,需要的朋友可以参考下
    2023-04-04
  • Spring事务框架之TransactionStatus源码解析

    Spring事务框架之TransactionStatus源码解析

    这篇文章主要为大家介绍了Spring事务框架之TransactionStatus源码示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Linux中配置Java环境变量实现过程

    Linux中配置Java环境变量实现过程

    文章介绍了在Linux系统上安装Java 1.8的步骤:下载、传输、解压至/opt目录,配置环境变量(当前用户或全局),使用update-alternatives设置默认版本,并通过命令验证安装是否成功
    2025-07-07
  • JavaWeb监听器Listener实例解析

    JavaWeb监听器Listener实例解析

    这篇文章主要为大家详细介绍了JavaWeb监听器Listener实例,针对监听器进行进行细致分析,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • JavaTCP上传图片代码实例

    JavaTCP上传图片代码实例

    今天小编就为大家分享一篇关于JavaTCP上传图片代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • java打印指定年月的日历

    java打印指定年月的日历

    这篇文章主要为大家详细介绍了Java如何打印指定年月的日历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07

最新评论