Spring boot 发送手机验证码

由于阿里云现在的短信签名无法通过申请,所以我这里选择了中国网建SMS短信平台(手机号注册即用,有免费赠送的几条短信测试)

demo代码地址:https://github.com/mer97/springboot-sendmessage

Spring boot 实现发送手机验证码功能:

依赖包:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-json'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'commons-httpclient:commons-httpclient:3.0.1'
    implementation 'commons-codec:commons-codec:1.4'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

工具类:

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

/**
 * @author LEEMER
 * Create Date: 2019-01-18
 */
public class SendMessageUtil {
    private static final String SMS_Url = "http://sms.webchinese.cn/web_api/";

    /**
     * @param Uid SMS用户id  : LEEMER
     * @param Key 接口秘钥:SMS登录可查(非登录密码)
     * @param sendPhoneNum 短信发送目标号码
     * @param desc 短信内容
     * @return Integer(1:成功码,其他失败,具体参见注释)
     */
    public static Integer send(String Uid,String Key,String sendPhoneNum,String desc){

        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod(SMS_Url);
        post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");// 在头文件中设置转码

        //设置参数
        NameValuePair[] data = {
                new NameValuePair("Uid", Uid),//登录用户名
                new NameValuePair("Key", Key),//秘钥
                new NameValuePair("smsMob", sendPhoneNum),
                new NameValuePair("smsText", desc)
        };

        post.setRequestBody(data);

        try {
            client.executeMethod(post);
        } catch (Exception e) {  e.printStackTrace();  }


        Header[] headers = post.getResponseHeaders();
        int statusCode = post.getStatusCode();
        System.out.println("statusCode:" + statusCode);
        for (Header h : headers) {
            System.out.println(h.toString());
        }

        String result ="";
        try {
            result = new String(post.getResponseBodyAsString().getBytes("gbk"));
        } catch (Exception e) {  e.printStackTrace();  }

        post.releaseConnection();

        return Integer.parseInt(result);
    }
    /**
     *  -1  没有该用户账户
     -2 接口密钥不正确 [查看密钥]不是账户登陆密码
     -21    MD5接口密钥加密不正确
     -3 短信数量不足
     -11    该用户被禁用
     -14    短信内容出现非法字符
     -4 手机号格式不正确
     -41    手机号码为空
     -42    短信内容为空
     -51    短信签名格式不正确接口签名格式为:【签名内容】
     -6 IP限制
     大于0    短信发送数量
     以上作为补充
     */
    public static String getMessage(Integer code){
        String message;
        if(code > 0 ) {
            message = "SMS-f发送成功!短信发送数量:" + code + "条";
        }else if(code == -1){
            message = "SMS-没有该用户账户";
        }else if(code == -2){
            message = "SMS-接口密钥不正确";
        }else if(code == -21){
            message = "SMS-MD5接口密钥加密不正确";
        }else if(code == -3){
            message = "SMS-短信数量不足";
        }else if(code == -11){
            message = "SMS-该用户被禁用";
        }else if(code == -14){
            message = "SMS-短信内容出现非法字符";
        }else if(code == -4){
            message = "SMS-手机号格式不正确";
        }else if(code == -41){
            message = "SMS-手机号码为空";
        }else if(code == -42){
            message = "SMS-短信内容为空";
        }else if(code == -51){
            message = "SMS-短信签名格式不正确接口签名格式为:【签名内容】";
        }else if(code == -6){
            message = "SMS-IP限制";
        }else{
            message = "其他错误";
        }
        return message;
    }

}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoApplicationTests.class);
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 生成随机数
     * @param num 位数
     * @return
     */
    public static String createRandomNum(int num){
        String randomNumStr = "";
        for(int i = 0; i < num;i ++){
            int randomNum = (int)(Math.random() * 10);
            randomNumStr += randomNum;
        }
        return randomNumStr;
    }

    /**
     * 中国网建 SMS短信
     */
    @Test
    public void sendMessage(){
        var timeout = 5;
        String code = createRandomNum(6);
        var sendPhoneNum = "137********";
        Integer resultCode = SendMessageUtil.send("LEEMER","d41d8*******",sendPhoneNum,"尊敬的用户,您好,您的验证码为:"+code+",请于"+timeout+"分钟内正确输入,如非本人操作,请忽略此短信。");
        System.out.println(SendMessageUtil.getMessage(resultCode));
        if (resultCode>0){
            System.out.println("已发送至:"+sendPhoneNum+",验证码:"+ code);
            //手机验证码发送成功。验证码存入Redis缓存
            redisTemplate.opsForValue().set(sendPhoneNum,code);
            redisTemplate.expire(sendPhoneNum,5, TimeUnit.MINUTES);
        }
    }

}

 

### Spring Boot 实现手机验证码登录功能 #### 设置短信验证码认证 Provider 类到 AuthenticationManager 中 为了实现基于手机号和验证码的登录,在 `Spring Security` 的配置中,需要自定义一个 `SmsCodeAuthenticationProvider` 并将其注册至 `AuthenticationManager`。这一步骤通过如下方式完成: ```java smsCodeAuthenticationProvider.setUserDetailsService(userDetailsService); // 注册UserDetailService实例给SmsCodeAuthenticationProvider对象[^1] authenticationManagerBuilder.authenticationProvider(smsCodeAuthenticationProvider); ``` 这段代码的作用在于将用户详情服务注入到短信验证提供者里,并把该提供者加入到身份验证管理者列表。 #### 创建请求模型类 对于前端传来的数据封装成实体类以便于处理,这里创建了一个名为 `CaptchaRequest` 的 Java Bean 来承载这些信息。此Bean包含了必填项——电话号码以及可能存在的其他字段比如图片验证码等附加属性。同时提供了相应的 getter 和 setter 方法方便访问私有成员变量。 ```java public class CaptchaRequest { @NotBlank(message = "手机号不能为空") private String phoneNumber; // 可选:如果业务逻辑中有图形验证码,则可以在此处声明相应字段 // Getter and Setter } ``` 上述代码片段展示了如何利用注解来确保输入的有效性并简化了开发流程[^2]。 #### 调用第三方 API 发送短信 当接收到客户端发起的身份验证请求之后,服务器端会生成随机数作为一次性密码并通过调用外部服务商提供的 HTTP 接口向指定移动设备推送消息通知。具体操作取决于所选用的服务商文档说明,通常涉及构建 POST 请求携带必要参数提交给网关地址等待响应确认发送成功与否。 ```java // 假设有一个 sendSms() 函数负责实际发出HTTP请求 sendSms(phoneNumber, generatedVerificationCode); ``` 以上过程描述了怎样借助第三方平台的能力快速有效地触达目标受众群体,从而提高用户体验满意度的同时也增强了系统的安全性[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值