让你的Demo更安全--Spring Boot实现短信验证码

随着移动互联网的普及,短信验证码已经成为了很多应用的常用登录和注册方式之一。在传统的应用中,我们一般使用第三方集成商提供的短信验证码服务来实现短信验证码的发送和验证,但是这些服务有可能存在时间限制、价格过高等限制。

为了解决这些问题,我们可以使用Spring Boot来自己实现短信验证码。在本文中,我将向大家介绍如何使用Spring Boot来实现短信验证码,并提供详细的开发流程和代码示例。


前置条件

在实现短信验证码之前,需要配置以下环境和依赖:

  • JDK 1.8或以上版本
  • Maven 3.5或以上版本
  • Spring Boot 2.0或以上版本
  • 阿里云短信服务

短信验证码的实现思路

在实现短信验证码之前,我们需要确定实现短信验证码需要哪些步骤:

  • 客户端向服务端发送手机号码
  • 服务端生成随机的验证码并发送到该手机号码
  • 客户端将验证码发送到服务端进行校验

根据这个思路,我们可以通过以下几个步骤来实现短信验证码:

  1. application.properties文件中配置阿里云短信服务的AccessKey和SecretKey:
# 阿里云短信服务的AccessKey
aliyun.sms.accessKeyId=your_accessKeyId
# 阿里云短信服务的SecretKey
aliyun.sms.accessKeySecret=your_accessKeySecret
  1. 定义短信验证码的请求和响应类:
public class SmsRequest {
    // 手机号码
    private String phone;
    // 验证码
    private String code;
    // 发送时间
    private Long timestamp;
    // 签名
    private String signature;
    // getter和setter方法
}

public class SmsResponse {
    // 发送状态码
    private String code;
    // 发送消息
    private String message;
    // getter和setter方法
}
  1. 定义短信发送接口:
public interface SmsService {
    /**
     * 发送短信验证码
     *
     * @param phone 手机号码
     * @return 发送状态
     */
    SmsResponse sendSms(String phone);
}
  1. 实现短信发送接口:
@Service
public class SmsServiceImpl implements SmsService {
    // 阿里云短信服务的AccessKey
    @Value("${aliyun.sms.accessKeyId}")
    private String ACCESS_KEY_ID;
    // 阿里云短信服务的SecretKey
    @Value("${aliyun.sms.accessKeySecret}")
    private String ACCESS_KEY_SECRET;
    // 验证码的有效时间,单位为秒
    private static final int EXPIRATION = 120;

    /**
     * 发送短信验证码
     *
     * @param phone 手机号码
     * @return 发送状态
     */
    @Override
    public SmsResponse sendSms(String phone) {
        SmsResponse response = new SmsResponse();
        try {
            DefaultProfile profile = DefaultProfile.getProfile("default", ACCESS_KEY_ID, ACCESS_KEY_SECRET);
            IAcsClient client = new DefaultAcsClient(profile);

            SendSmsRequest request = new SendSmsRequest();

            // 设置短信模板
            request.setTemplateCode("SMS_123456789");

            // 生成验证码
            String code = String.valueOf((int)((Math.random()*9+1)*100000));

            // 将验证码保存到Redis缓存中
            jedis.setex(phone, EXPIRATION, code);

            Map<String, String> map = new HashMap<>(1);
            map.put("code", code);

            // 设置短信参数
            request.setTemplateParam(new Gson().toJson(map));

            request.setPhoneNumbers(phone);

            // 发送
            SendSmsResponse smsResponse = client.getAcsResponse(request);

            if (smsResponse.getCode() != null && smsResponse.getCode().equals("OK")) {
                response.setCode("200");
                response.setMessage("验证码发送成功");
            } else {
                response.setCode("500");
                response.setMessage("验证码发送失败,请稍后再试");
            }
        } catch (Exception e) {
            response.setCode("500");
            response.setMessage("验证码发送失败,请稍后再试");
            e.printStackTrace();
        }
        return response;
    }
}

在上述示例代码中,我们使用阿里云短信服务的SDK发送短信,首先从配置文件中获取AccessKey和SecretKey,然后生成IAcsClient对象,并设置模板代码,生成验证码并保存到Redis缓存中,最后发送短信。

  1. 创建接口Controller:
@RestController
@RequestMapping("/api/sms")
public class SmsController {

    private final SmsService smsService;

    public SmsController(SmsService smsService) {
        this.smsService = smsService;
    }

    /**
     * 发送短信验证码
     * @param phone 手机号码
     * @return 发送状态
     */
    @GetMapping("/send")
    public SmsResponse sendSms(@RequestParam("phone") String phone) {
        return smsService.sendSms(phone);
    }
}

在上面代码中,我们创建了一个发送短信验证码的接口,并使用@GetMapping注解将其映射到/api/sms/send路径上。

  1. 实现验证码校验:
@RestController
@RequestMapping("/api/sms")
public class SmsController {

    private final SmsService smsService;

    public SmsController(SmsService smsService) {
        this.smsService = smsService;
    }

    /**
     * 发送短信验证码
     * @param phone 手机号码
     * @return 发送状态
     */
    @GetMapping("/send")
    public SmsResponse sendSms(@RequestParam("phone") String phone) {
        return smsService.sendSms(phone);
    }

    /**
     * 校验验证码
     * @param request 校验请求
     * @return 校验结果
     */
    @PostMapping("/verify")
    public ResponseEntity<?> verifySms(@RequestBody SmsRequest request) {
        String code = jedis.get(request.getPhone());
        if (code != null && code.equals(request.getCode())) {
            jedis.del(request.getPhone());
            return ResponseEntity.ok("验证码校验成功");
        } else {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("验证码校验失败");
        }
    }
}

在上述代码中,我们创建了一个校验短信验证码的接口,并使用@PostMapping注解将其映射到/api/sms/verify路径上。在接口实现中,我们从Redis缓存中获取验证码,若验证码有效,则从Redis缓存中删除验证码并返回成功响应,否则返回失败响应。

  1. 使用Redis缓存:
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
        return new JedisConnectionFactory(redisStandaloneConfiguration);
    }

    @Bean
    RedisTemplate<String, Object> redisTemplate() {
        final RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        template.setValueSerializer(new GenericToStringSerializer<>(Object.class));
        return template;
    }
}

在上述代码中,我们创建了一个Redis配置类,并使用@Configuration注解将其标注为配置类。在jedisConnectionFactory方法中,我们设置了Redis服务器的IP和端口,并返回一个JedisConnectionFactory对象,用于获取Jedis实例。在redisTemplate方法中,我们创建了一个RedisTemplate对象,并设置了序列化器和连接工厂。

至此,我们已经完成了短信验证码的实现。

总结

Spring Boot为我们提供了快速便捷地实现短信验证码功能的方式。在本文中,我向大家展示了使用阿里云短信服务发送短信验证码并实现验证码校验的代码示例。如果您打算实现短信验证码功能,可以参考本文提供的思路和代码示例。

在实际开发中,我们还可以根据业务需求对短信验证码进行更多的优化和改进,比如添加验证码图形识别、增加短信发送次数校验、防止恶意发送、短信的批量发送等功能。

总之,短信验证码是现在很常见的一种验证方式,其简单、便捷、安全的特点获得了很多企业和应用的青睐。希望本文可以对您实现短信验证码功能有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/24084.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Z-Library2023现状

网上基本上年年都会传出来Z-Library要被干掉的消息&#xff0c;我一直觉得&#xff0c;如果那真的发生了&#xff0c;会是人类的悲哀。 由于之前我存储的地址又挂了&#xff0c;所以紧急又寻找了一下。 1.朋友帮忙 朋友帮我搜了一下&#xff0c;发现有三个地址。 他说这第一个…

xlsx是什么格式

xlsx是什么格式? xlsx是Excel文档的扩展名&#xff0c;其基于Office Open XML标准的压缩文件格式&#xff0c;取代了其以前专有的默认文件格式&#xff0c;在传统的文件名扩展名后面添加了字母x&#xff0c;即.xlsx取代.xls。 xlsx文件是什么格式? xlsx是Excel表格的文件格…

【P34】JMeter ForEach控制器(ForEach Controller)

文章目录 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明二、准备工作三、测试计划设计 一、ForEach控制器&#xff08;ForEach Controller&#xff09;参数说明 可以对一个组变量进行循环迭代&#xff1b;该组件通常与后置处理器中的 JSON 提取器、正…

桥梁结构健康监测解决方案

城市桥梁担负着城市的交通和运输网络的重要角色&#xff0c;是城市生命线的重要组成部分。然而&#xff0c;随着时间的推移和日益增长的负荷&#xff0c;桥梁可能会受到各种因素的损害&#xff0c;如自然灾害、疲劳、腐蚀等。因此&#xff0c;桥梁结构健康监测变得至关重要&…

chatgpt赋能Python-python中怎么导入numpy

介绍 Python是一种广泛使用的编程语言&#xff0c;具有许多内建功能和模块&#xff0c;让开发者能够快速地编写代码。然而&#xff0c;虽然能够实现许多计算&#xff0c;但是原始Python本身并不足够处理各种科学和数字计算上需要的高效性&#xff0c;因此numpy这个开源的Pytho…

【机器学习】采样方法

文章目录 采样方法11.1 简介11.2 常见采样方法11.2.1 均匀分布采样11.2.2 逆变换采样11.2.3 拒绝采样11.2.4 重要采样11.2.5 Metropolis方法11.2.6 Metropolis-Hasting 算法11.2.7 吉布斯采样 采样方法 11.1 简介 什么是采样 从一个分布中生成一批服从该分布的样本&#xff0c…

JavaWeb ( 十 ) SpringMVC

4.Spring MVC Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。 三层架构分为表述层&#xff08;或表示层)、业务逻辑层、数据访问层&#xff0c;表述层表示前台页面和后台servlet 4.1.Spring MVC优点&#xff1a; ① 基于原生的Servlet&#xff0c;通过…

API测试| 了解API接口测试| API接口测试指南

什么是API&#xff1f; API是一个缩写&#xff0c;它代表了一个 pplication P AGC软件覆盖整个房间。API是用于构建软件应用程序的一组例程&#xff0c;协议和工具。API指定一个软件程序应如何与其他软件程序进行交互。 例行程序&#xff1a;执行特定任务的程序。例程也称为过…

MKS SERVO4257D 闭环步进电机_系列1 产品简介

第1部分 产品概述 1.1 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口&#xff0c;RS485接口和CAN接口&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&#xff0c;有…

【工具】vscode的常用插件之git插件

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

进程间通信(命名管道)

目录&#xff1a; 1.命名管道 2.创建命名管道 --------------------------------------------------------------------------------------------------------------------------------- 1.命名管道 1.管道的一个应用限制就是只能在具有共同祖先&#xff08;具有亲缘关系&…

网络编程初识

如果这篇有没接触过的知识点&#xff0c;请转到网络编程先导知识_小梁今天敲代码了吗的博客-CSDN博客 目录 IPv4和IPv6的概念&#xff1a; 子网掩码 默认网关 ping命令 端口 OSI网络分层模型 TCP/IP四层模型 字节序转换函数 IP地址转换 上一篇介绍了网络编程的先导知…

2023五一赶制个人系统:基于SpringBoot+MyBatisPlus+Vue+ElementUI前后端分离

小钊记前言 &#x1f351;一、背景&#x1f351;二、调研准备阶段&#x1f34a;2.1、项目-自己搭建&#x1f353; 搭建步骤 &#x1f34a;2.2、项目需求-自己X造&#x1f34a;2.2、数据模型设计 &#x1f351;三、开发阶段&#x1f351;四、renxiaozhao 1.0.0-alpha发布&#x…

SpringBoot配置文件的注入和读取

目录 1. 配置文件的作用 2. 两种配置文件的格式&#xff1a; 2.1 properties 基本语法&#xff1a; 2.1.1 写入 2.1.2 读取 执行原理 2.1.3 缺点分析 2.2 yml 基本语法&#xff1a; 2.2.1 写入&#xff08;非对象&#xff09; 2.2.3 配置对象 2.2.4 配置集合 多个配…

Python爬虫

爬虫流程 爬虫流程&#xff1a;获取网页内容 --> 解析网页内容 --> 储存或分析数据 爬虫规则&#xff1a; 1、不要爬取公民隐私数据 2、不要爬取受著作保护的内容 3、不要爬取国家事务、国防建设、尖端科学计数领域的计算机系统等 4、请求数量和频率不能太高&…

MOTOTRBO CPS2.0安装与写频流程

一、安装MOTOTRBO CPS2.0写频软件 安装MOTOTRBO CPS2.0写频软件&#xff0c;选择安装软件的电脑系统必须WIN7以上 1.解压CPS2_2.21.61.0.zip至当前文件内 2. 双击MOTOTRBO_CPS_2.0.exe安装文件 3. 选择安装语言中文&#xff08;简体&#xff09;&#xff0c;点击确定 4.点击下一…

「实在RPA·人社数字员工」促进人力社保数字办公战略转型

一、人力社保部门数字化转型的重要性 伴随着国家放宽人力资源市场准入条例&#xff0c;多次出台相关扶持政策&#xff0c;市场竞争加剧&#xff0c;后疫情时代格局的大变局&#xff0c;如何提高服务质量和效率&#xff0c;如何降本增效&#xff0c;成为人力资源和社会保障行业…

Educational Codeforces Round 139 (Rated for Div. 2)

Educational Codeforces Round 139 (Rated for Div. 2) Problem - 1766E - Codeforces 显然我们可以把0序列的贡献单独算: i*(n-i1) 考虑只存在1,2,3的情况. 首先通过&#xff0c;观察到一个重要性质: 最多只有三种序列. 含有3或纯1或纯2型.纯1或纯2型纯2或纯1型 我们每次添加…

hugging face开源的transformers模型可快速搭建图片分类任务

2017年,谷歌团队在论文「Attention Is All You Need」提出了创新模型,其应用于NLP领域架构Transformer模型。从模型发布至今,transformer模型风靡微软、谷歌、Meta等大型科技公司。且目前有模型大一统的趋势,现在transformer 模型不仅风靡整个NLP领域,且随着VIT SWIN等变体…

什么是高性能计算实习生?做高性能计算有前景吗?

随着大模型和算力时代的大火&#xff0c;高性能计算实习的岗位越来越多了&#xff0c;各个大厂都在码人&#xff0c;百度、小米、字节、华为等等&#xff0c;也有很多网友晒出了面试一众知名芯片企业的面经和笔试题。 但是依然有很多朋友不清楚什么是高性能计算实习生&#xf…