文章目录

  • 前言
  • 一、环境准备
  • 二、测试代码
  • 1.引入库
  • 2.编写验证码生成工具类
  • 3.编写短信发送工具类
  • 4.编写发送验证码与注册控制层
  • 5.测试页面
  • 6.测试结果
  • 总结



前言

现在通过Springboot或是SSM做项目避免不开验证功能的实现,通常的验证方式有手机验证码、邮箱验证码、静态随机验证码等。本文主要介绍学生项目开发中手机验证码的实现。


一、环境准备

现主流运用的第三方短信接口平台很多,博主这边尝试了阿里云短信服务与腾讯云短信服务。这两个平台都有免费试用的通知短信,现在的免费额度都是200条,后续套餐的话腾讯云是3分多一条短信而阿里云是4分多一条短信。再加上申请条件方面的难易,我还是比较推荐腾讯云的短信服务的,这边的案例实现也是基于腾讯云的短信服务实现的。

鉴于现在对虚假诈骗行为的防范,申请各平台的短信服务是需要申请条件的。

  • 申请到阿里云可用的短信服务需要的硬性条件:已备案的域名网址或者是已上线的APP
  • 申请到腾讯云可用的短信服务需要的硬性条件:已备案的域名网址或者是已上线的APP以及已认证的公众号

对于学生来说已备案的域名网址或者是已上线的APP可实现难度还是比较打的,相比之下腾讯云的公众号申请短信服务来的更亲民些。

  1. 登录腾讯云找到控制台搜索“短信服务”进入到短信服务页面
  2. docker部署springboot验证码不显示 springboot 短信验证码_json

  3. 创建应用
  4. docker部署springboot验证码不显示 springboot 短信验证码_json_02

  5. 可以根据不用的业务创建不同的应用以区分
  6. docker部署springboot验证码不显示 springboot 短信验证码_json_03

  7. 应用创建好后点击相应的应用可以查看该应用信息,其中的SDK_AppID与App Key是我们需要的数据。
  8. 创建签名与正文模板
  • 创建签名
  • docker部署springboot验证码不显示 springboot 短信验证码_Code_04

  • 这里创建的签名是利用我自己的公众号去申请的,个人公众号的注册并不难,可以直接在微信公众平台注册。
  • docker部署springboot验证码不显示 springboot 短信验证码_json_05

  • 确认无误就可以提交申请了,官方审核一般工作时间两个小时内就有结果了,还是挺容易过审的。
  • 创建正文模板
  • docker部署springboot验证码不显示 springboot 短信验证码_json_06

  • 正文模板这有一个ID,这也是一个很重要的参数,程序中也会用到,在程序中为templateID,也就是模板ID。
  • docker部署springboot验证码不显示 springboot 短信验证码_java_07

  • 如果签名不过审正文模板也会不过审的,所以官方要求的信息还是要认真填给他的

签名与正文模板过审后我们就得到了我们需要的四个重要参数:

  • 短信应用SDK AppID 1400开头
  • 短信应用SDK AppKey
  • 短信模板ID
  • 签名 即签名内容

#由于手机供应商亦或是手机设置,当测试验证码发送到一定数量时,手机会屏蔽腾讯云短信服务发来的短信,故需要设置手机白名单

docker部署springboot验证码不显示 springboot 短信验证码_json_08

二、测试代码

1.引入库

Maven代码如下:

<!--腾讯云手机验证-->
        <dependency>
            <groupId>com.tencentcloudapi</groupId>
            <artifactId>tencentcloud-sdk-java</artifactId>
            <version>3.1.87</version>
        </dependency>
        <dependency>
            <groupId>com.github.qcloudsms</groupId>
            <artifactId>qcloudsms</artifactId>
            <version>1.0.6</version>
        </dependency>

这两个依赖导入需要点时间,确保在网络条件好的情况下导入。不然会出现依赖导入一半没成功导入但文件又在仓库中存在,导致后续依赖难以再导入!踩过此坑,含泪劝告~

2.编写验证码生成工具类

keyUtil 代码如下:

import java.util.Random;

public class keyUtil {
    public static String keyUtils() {
        String str="0123456789";
        StringBuilder st=new StringBuilder(4);
        for(int i=0;i<4;i++){
            char ch=str.charAt(new Random().nextInt(str.length()));
            st.append(ch);
        }
        String findkey=st.toString().toLowerCase();
        return findkey;
    }
}

3.编写短信发送工具类

SMSUtil 代码如下:

import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import org.json.JSONException;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SMSUtil {
    public static String code1=null;
    public static long time1;
    public static String sendSMS(HttpServletRequest request, String tel) {
        String reStr = ""; //定义返回值
        // 短信应用SDK AppID  1400开头
        int appid = 1400****** ;
        // 短信应用SDK AppKey
        String appkey = "d706*************************";
        // 短信模板ID,需要在短信应用中申请
        int templateId = 10***** ;
        // 签名,使用的是签名内容,而不是签名ID
        String smsSign = "****";
        //随机生成四位验证码的工具类
        String code = keyUtil.keyUtils();
        code1=code;
        try {
            //参数,一定要对应短信模板中的参数顺序和个数,
            String[] params = {code};
            //创建ssender对象
            SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
            //发送
            SmsSingleSenderResult result = ssender.sendWithParam("86", tel,templateId, params, smsSign, "", "");
            if(result.result!=0){
                reStr = "error";
            }
            // 签名参数未提供或者为空时,会使用默认签名发送短信
            HttpSession session = request.getSession();
            //JSONObject存入数据
            JSONObject json = new JSONObject();
            json.put("Code", code);//存入验证码
            time1=System.currentTimeMillis();
            json.put("createTime", System.currentTimeMillis());//存入发送短信验证码的时间
            // 将验证码和短信发送时间码存入SESSION
            request.getSession().setAttribute("Code",code);
            request.getSession().setAttribute("MsCode", json);
            System.out.println(json);
            reStr = "success";
        } catch (HTTPException e) {
            // HTTP响应码错误
            e.printStackTrace();
        } catch (JSONException e) {
            // json解析错误
            e.printStackTrace();
        } catch (IOException e) {
            // 网络IO错误
            e.printStackTrace();
        }catch (Exception e) {
            // 网络IO错误
            e.printStackTrace();
        }
        return reStr;
    }

}

4.编写发送验证码与注册控制层

代码如下(示例):

//点击发送验证码
    @PostMapping("/sendMs")
    @ResponseBody
    public String sendMs (HttpServletRequest request, String phoneNumber){
        if(phoneNumber!=null&&!phoneNumber.equals("")){
            String s = SMSUtil.sendSMS(request,phoneNumber);
            return s;
        }else{
            return "error";
        }
    }

//登录验证
@PostMapping("/register")
    @ResponseBody
    public Object register(HttpServletRequest request, String Code) {
        JSONObject json = (JSONObject)request.getSession().getAttribute("MsCode");
        if(!json.getString("Code").equals(Code)){
            return "验证码错误";
        }
        //我这里模拟了一分钟
        if((System.currentTimeMillis() - json.getLong("createTime")) > 1000 * 60 * 1){
            return "验证码过期";
        }
        //将用户信息存入数据库、这里省略
        return "success";
    }

5.测试页面

代码如下:

<!DOCTYPE html>
<!--suppress ALL-->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="@{/}"><!-- 不用base就使用th:src="@{/js/jquery.min.js} -->
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<script src="js/jquery.min.js"></script>
<script src="js/common.js"></script>
<style>
	/*login页面*/
	body{
		background-color: darkgray;
	}
	.container{
		border: 1px solid rgba(255,255,255,0.3);
		margin-top: 100px;
		width: 60%;
		margin-left: 40%;
	}
	#l1,#l2,#l3,#l4{
		color: white;
	}

</style>
<body>
	<div class="container">
		<div style="width:70%; height: 60px;padding-top: 1px;">
	       <h2 align="center" style="color: white;font-size: 25px">用户登录</h2>
	   </div>
		<br><br>
		<form action="log" name="myform" method="post" role="form">
			<div >
				<label>手机号</label>
				<div>
					<input type="tel"  id="phoneNumber"
					 placeholder="请输入您的手机号码"/>
					<span></span>
				</div>
			</div>
			 
			 <div>
				  <label>验证码</label>
				  <div>
				  		<table style="width: 100%">
				  			<tr >
				  				<td><input type="text" id="Code"
					 				placeholder="请输入验证码" /></td>
					 			<td height="34px">
									<input type="button" value="发送验证码" id="sendBtn">
					 			</td>
				  			</tr>
				  		</table>
				  </div>
			 </div>

			<div>
				<div>
					<button type="button" id="login">登录</button>
					<button type="reset">重置</button>
				</div>
			</div>

		</form>

	</div>
</body>

<script>

	//添加发送验证码按钮的点击事件
	$("#sendBtn").click(function () {
		var phoneNumber=$("#phoneNumber").val();
		$.post("/essc/sendMs",{"phoneNumber":phoneNumber},function (data) {
			alert("请在手机查看验证码");
		});

	});

	//给登录按钮添加点击事件
	$("#login").click(function () {
		//获取验证码 判断不为空的时候,显示点击按钮
		var Code=$("#Code").val();
		if((Code!=null&&Code!="")){
			var url="/essc/login";
			var param={"Code":Code};
			$.post(url,param,function (data) {
				alert("验证码已校正");
			});
		}
	});
</script>

</html>

该处用的html只是作为测试功能用,比较简略。采用ajax请求与后端交互,需要引入jquery源

6.测试结果

docker部署springboot验证码不显示 springboot 短信验证码_验证码_09

测试页面中点击发送验证码手机端收到验证码,登录按钮可以结合自己要实现的业务进行适当调整调用。

docker部署springboot验证码不显示 springboot 短信验证码_Code_10


总结

通过此文相信你可以很容易使用第三方服务平台的短信服务用来测试实现手机验证码验证,很多其他第三方平台的短信服务与此也大同小异,故学会这一个就可以举一反三了。