若依框架中实现短信验证码发送功能

2025-06发布2次浏览

在若依框架中实现短信验证码发送功能,需要结合后端逻辑、前端交互以及第三方短信服务提供商的API来完成。以下是详细的实现步骤和代码示例。


一、需求分析

  1. 功能描述:用户输入手机号后,系统向该手机号发送一条包含验证码的短信,验证码用于验证用户身份。
  2. 技术栈
    • 后端:基于Spring Boot(若依框架)。
    • 前端:Vue.js 或其他前端框架。
    • 第三方服务:阿里云短信、腾讯云短信或其他短信服务。
  3. 流程概述
    • 用户在前端页面输入手机号并触发“获取验证码”按钮。
    • 后端生成随机验证码并存储到缓存(如Redis)中。
    • 调用第三方短信服务发送验证码。
    • 用户提交验证码进行验证。

二、实现步骤

1. 引入依赖

pom.xml中引入必要的依赖,例如Redis和第三方短信服务SDK。

<!-- Redis依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 阿里云短信SDK(以阿里云为例) -->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.5.0</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>1.1.0</version>
</dependency>

2. 配置文件设置

application.yml中添加相关配置:

# 短信服务配置
sms:
  accessKeyId: your_access_key_id
  accessKeySecret: your_access_key_secret
  signName: 若依科技
  templateCode: SMS_123456789

# Redis配置
spring:
  redis:
    host: localhost
    port: 6379
    password: 
    timeout: 10000
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

3. 创建短信发送工具类

编写一个工具类用于封装短信发送逻辑。

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SmsUtil {

    @Value("${sms.accessKeyId}")
    private String accessKeyId;

    @Value("${sms.accessKeySecret}")
    private String accessKeySecret;

    @Value("${sms.signName}")
    private String signName;

    @Value("${sms.templateCode}")
    private String templateCode;

    public SendSmsResponse sendSms(String phone, String code) throws ClientException {
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        SendSmsRequest request = new SendSmsRequest();
        request.setPhoneNumbers(phone);
        request.setSignName(signName);
        request.setTemplateCode(templateCode);
        request.setTemplateParam("{\"code\":\"" + code + "\"}");

        return client.getAcsResponse(request);
    }
}

4. 缓存验证码

使用Redis缓存验证码,设置过期时间为5分钟。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class CaptchaService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SmsUtil smsUtil;

    public String generateCaptcha(String phone) throws Exception {
        // 生成6位随机验证码
        Random random = new Random();
        StringBuilder captcha = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            captcha.append(random.nextInt(10));
        }

        // 将验证码存入Redis,设置过期时间
        String key = "captcha:" + phone;
        redisTemplate.opsForValue().set(key, captcha.toString(), 5, TimeUnit.MINUTES);

        // 发送短信
        smsUtil.sendSms(phone, captcha.toString());

        return "验证码已发送,请查收短信";
    }

    public boolean validateCaptcha(String phone, String captcha) {
        String key = "captcha:" + phone;
        String cachedCaptcha = redisTemplate.opsForValue().get(key);
        if (cachedCaptcha == null || !cachedCaptcha.equals(captcha)) {
            return false;
        }
        redisTemplate.delete(key); // 验证成功后删除验证码
        return true;
    }
}

5. 控制器实现

定义接口供前端调用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/sms")
public class SmsController {

    @Autowired
    private CaptchaService captchaService;

    @PostMapping("/send")
    public String sendCaptcha(@RequestParam String phone) {
        try {
            return captchaService.generateCaptcha(phone);
        } catch (Exception e) {
            return "发送失败:" + e.getMessage();
        }
    }

    @PostMapping("/validate")
    public Boolean validateCaptcha(@RequestParam String phone, @RequestParam String captcha) {
        return captchaService.validateCaptcha(phone, captcha);
    }
}

6. 前端交互示例

以下是一个简单的Vue.js示例,展示如何调用后端接口。

<template>
  <div>
    <input v-model="phone" placeholder="请输入手机号" />
    <button @click="sendCaptcha">获取验证码</button>
    <input v-model="captcha" placeholder="请输入验证码" />
    <button @click="validateCaptcha">验证</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      phone: "",
      captcha: ""
    };
  },
  methods: {
    sendCaptcha() {
      this.$axios.post("/sms/send", { phone: this.phone })
        .then(response => {
          alert(response.data);
        });
    },
    validateCaptcha() {
      this.$axios.post("/sms/validate", { phone: this.phone, captcha: this.captcha })
        .then(response => {
          if (response.data) {
            alert("验证通过");
          } else {
            alert("验证失败");
          }
        });
    }
  }
};
</script>

三、流程图

以下是短信验证码发送与验证的整体流程图。

sequenceDiagram
    participant User
    participant Frontend
    participant Backend
    participant Redis
    participant SMSProvider

    Note over User,Frontend: 用户输入手机号
    User->>Frontend: 点击“获取验证码”
    Frontend->>Backend: POST /sms/send
    Backend->>Redis: 生成验证码并存储
    Redis-->>Backend: 返回验证码
    Backend->>SMSProvider: 调用短信接口发送验证码
    SMSProvider-->>Backend: 返回发送结果
    Backend-->>Frontend: 返回结果
    Frontend-->>User: 提示“验证码已发送”

    Note over User,Frontend: 用户输入验证码
    User->>Frontend: 点击“验证”
    Frontend->>Backend: POST /sms/validate
    Backend->>Redis: 查询验证码
    alt 验证码存在且匹配
        Redis-->>Backend: 返回验证码
        Backend-->>Frontend: 返回true
    else 验证码不存在或不匹配
        Redis-->>Backend: 返回null
        Backend-->>Frontend: 返回false
    end

四、总结

通过上述步骤,我们实现了基于若依框架的短信验证码发送与验证功能。该功能不仅提升了用户体验,还增强了系统的安全性。