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

45 篇文章 9 订阅
42 篇文章 1 订阅

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

为了解决这些问题,我们可以使用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为我们提供了快速便捷地实现短信验证码功能的方式。在本文中,我向大家展示了使用阿里云短信服务发送短信验证码并实现验证码校验的代码示例。如果您打算实现短信验证码功能,可以参考本文提供的思路和代码示例。

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

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙漠真有鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值