Java+阿裡雲手機驗證碼發送和驗證
1.注冊阿裡雲賬号,找到産品與服務裡面的雲通信子產品,然後找到短信服務
2.開通短信服務
我這裡已經開通,可直接進入管理控制台,沒開通的話這裡顯示開開通短信服務
3.進入管理控制台之後選擇國内消息,可以看到簽名管理和模闆管理
4.在此之前必須設定好AccessKey
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-p9jit6AQ-1572527330522)(C:\Users\Administrator\Desktop\短信服務\img\accesskeys.png)]
5.簽名和模闆具體可以參考右上角簽名和模闆,一般個人使用者稽核很快就通過了
6.一般簽名就是收到的短信的開頭(項目名或者公司名)
7.短信模闆
模闆内容就是收到短信的内容,${code}代表收到的驗證碼,模闆名稱就跟簽名一樣吧,申請說明就寫個人網站使用。
8.Java代碼實作
添加maven依賴
<!-- =========================阿裡雲短信驗證服務======================== -->
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-dysmsapi -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
配置AliyunSmsUtils(建立一個AliyunSmsUtils工具類)
public class AliyunSmsUtils {
//産品名稱:雲通信短信API産品,開發者無需替換
static final String product = "Dysmsapi";
//産品域名,開發者無需替換
static final String domain = "dysmsapi.aliyuncs.com";
// TODO 此處需要替換成開發者自己的AK(在阿裡雲通路控制台尋找)
static final String accessKeyId = ""; // TODO 修改成自己的
static final String accessKeySecret = ""; // TODO 修改成自己的
public static SendSmsResponse sendSms(String telephone, String code) throws ClientException {
//可自助調整逾時時間
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暫不支援region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//組裝請求對象-具體描述見控制台-文檔部分内容
SendSmsRequest request = new SendSmsRequest();
//必填:待發送手機号
request.setPhoneNumbers(telephone);
//必填:短信簽名-可在短信控制台中找到
request.setSignName(""); // TODO 修改成自己的 自己申請的簽名
//必填:短信模闆-可在短信控制台中找到
request.setTemplateCode("SMS_174991040"); // TODO 修改成自己的 模闆管理中模闆CODE
//可選:模闆中的變量替換JSON串,如模闆内容為"親愛的${name},您的驗證碼為${code}"時,此處的值為
// request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
request.setTemplateParam("{\"code\":\"" + code + "\"}");
//選填-上行短信擴充碼(無特殊需求使用者請忽略此字段)
//request.setSmsUpExtendCode("90997");
//可選:outId為提供給業務方擴充字段,最終在短信回執消息中将此值帶回給調用者
request.setOutId("yourOutId");
//hint 此處可能會抛出異常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
System.out.println("短信發送成功!");
} else {
System.out.println("短信發送失敗!");
}
return sendSmsResponse;
}
/* 不删 留着 以後可能有用
public static QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException {
//可自助調整逾時時間
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暫不支援region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//組裝請求對象
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
//必填-号碼
request.setPhoneNumber("15000000000");
//可選-流水号
request.setBizId(bizId);
//必填-發送日期 支援30天内記錄查詢,格式yyyyMMdd
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
request.setSendDate(ft.format(new Date()));
//必填-頁大小
request.setPageSize(10L);
//必填-目前頁碼從1開始計數
request.setCurrentPage(1L);
//hint 此處可能會抛出異常,注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
return querySendDetailsResponse;
}
*/
private static int newcode;
public static int getNewcode() {
return newcode;
}
public static void setNewcode(){
newcode = (int)(Math.random()*999999)+100; //每次調用生成一位六位數的随機數
}
// 傳入手機号獲得驗證碼的方法
public static String getTelnoCode(Long userTelno) {
String telno = Long.toString(userTelno);
setNewcode();
String code = Integer.toString(getNewcode());
System.out.println("發送的驗證碼為:" + code);
//發短信
SendSmsResponse response = null; // TODO 填寫你需要測試的手機号碼
try {
response = sendSms(telno, code);
} catch (ClientException e) {
e.printStackTrace();
}
System.out.println("短信接口傳回的資料----------------");
System.out.println("Code=" + response.getCode());
System.out.println("Message=" + response.getMessage());
System.out.println("RequestId=" + response.getRequestId());
System.out.println("BizId=" + response.getBizId());
return code;
}
/* public static void main(String[] args) throws ClientException, InterruptedException {
setNewcode();
String code = Integer.toString(getNewcode());
System.out.println("發送的驗證碼為:"+code);
//發短信
SendSmsResponse response =sendSms("13955410398",code); // TODO 填寫你需要測試的手機号碼
System.out.println("短信接口傳回的資料----------------");
System.out.println("Code=" + response.getCode());
System.out.println("Message=" + response.getMessage());
System.out.println("RequestId=" + response.getRequestId());
System.out.println("BizId=" + response.getBizId());
*/
/* 不删 留着 以後可能有用
System.out.println(" ============================================== ");
Thread.sleep(3000L);
//查明細
if(response.getCode() != null && response.getCode().equals("OK")) {
QuerySendDetailsResponse querySendDetailsResponse = querySendDetails(response.getBizId());
System.out.println("短信明細查詢接口傳回資料----------------");
System.out.println("Code=" + querySendDetailsResponse.getCode());
System.out.println("Message=" + querySendDetailsResponse.getMessage());
int i = 0;
for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs())
{
System.out.println("SmsSendDetailDTO["+i+"]:");
System.out.println("Content=" + smsSendDetailDTO.getContent());
System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
System.out.println("OutId=" + smsSendDetailDTO.getOutId());
System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
}
System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
}*/
}
前端頁面
前端注冊我用的模态框做的 附代碼
<!-- //注冊-->
<div class="modal-body regist-show" >
<form class="form-horizontal" role="form">
<div class="form-group">
<span class="col-sm-2 phone-icon"></span>
<div class="col-sm-10">
<input type="text" class="form-control phone-num" id="firstname phone-num" placeholder="請輸入手機号碼">
</div>
</div>
<div class="form-group">
<span class="col-sm-2 code-icon"></span>
<div class="col-sm-10">
<input type="text" class="form-control phone-code" id="lastname phone-code" placeholder="請輸入手機收到的驗證碼">
<input type="button" value="擷取驗證碼" class="get-code" id="get-code">
</div>
</div>
<div class="form-group">
<span class="col-sm-2 pw-icon" ></span>
<div class="col-sm-10 ">
<input type="password" class="form-control password" id="password" placeholder="密碼為6-18個字元">
</div>
</div>
Ajax向伺服器傳資料
/**
* 擷取驗證碼
*/
var get_code = document.querySelector("#get-code");//擷取驗證碼按鈕
var phone_num = document.querySelector(".phone-num");//注冊時候手機号
get_code.onclick = function () {
console.log(phone_num.value);
if (phone_num_verification() == true){
$.ajax({
url: "/btdev/user/getCode",
type: "POST",
data:{
"telno": phone_num.value //将手機号傳到伺服器
},
datatype: "json",
success:function (result) { //result背景傳回的資料
if(result.code==1){
console.log("可以注冊");
sms=result.data;
console.log(sms);
}else{
console.log("該手機号已經被注冊,請直接登入");
console.log(result.data);
validation_tip.innerText = result.data;
}
}
})
}
};
Java處理收到的手機号
@PostMapping("user/getCode")
public JsonResult getCode(long telno){
AliyunSmsUtils aliyunSmsUtils = new AliyunSmsUtils();
JsonResult jsonResult = userService.getByTelno(telno);
System.out.println(jsonResult);
if (jsonResult.getCode()==1){ //判斷使用者是否存在 1代表沒用查到
return new JsonResult(1,"沒查到,可直接注冊", AliyunSmsUtils.getTelnoCode(telno));
} else {
return new JsonResult(0,"使用者已注冊 可直接登入","該手機号已經被注冊,請直接登入");
}
}
userService.getByTelno方法
//判斷手機号是否已經注冊
public JsonResult getByTelno(Long userTelno) {
User user = null;
UserExample example = new UserExample();
UserExample.Criteria criteria = example.createCriteria();
criteria.andUsersTelnoEqualTo(userTelno);
criteria.andStatusEqualTo(0);
List<User> users = userMapper.selectByExample(example);
if (users.size()!=0){
user = users.get(0);
return new JsonResult(0,"查詢到該使用者,手機号已注冊",user);
}else{
return new JsonResult(1,"沒有查詢到該手機使用者 可以注冊",user);
}
}
JsonResult類(自定義的一種json格式)
package com.baitiao.util;
public class JsonResult {
/**
* 0 成功,1 失敗
*/
private int code;
private String message;
private Object data;
public JsonResult(){}
public JsonResult(int code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "JsonResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
進行驗證注冊 注意:我是在前端驗證發送的驗證碼與使用者輸入是否一緻,這是不安全的,可以通過轉包擷取。實際開發中需要在後端判斷發送的驗證碼與使用者輸入是否一緻
/**
* 單擊注冊按鈕後的操作
*/
var phone_code = document.querySelector(".phone-code");//輸入驗證碼得值
regist_mit.onclick = function () {
password_verification();
console.log(sms);
console.log(phone_code.value);
console.log(phone_num.value);
console.log(pw.value);
if (phone_code.value==""){
validation_tip.innerText = "驗證碼不能為空"
} else {
if (password_verification()== true && (sms==phone_code.value) ) {//password_verification()是自己寫的一個密碼格式驗證的方法,
$.ajax({
url:"/btdev/user/regist",
type:"POST",
data:{
"telno" :phone_num.value,//将資料傳輸到伺服器
"pw":pw.value
},
datatyep:"json",
success:function (result) {
console.log("kk");
console.log(sms);
console.log(result.code);
console.log(result.data);
if (result.code==0){
layer.msg("注冊成功,正在前往登入界面",{icon:1,time:1500,offset: '300px',shade: 0.3},function(){ //layui的提示框 大家可以用用很友善
regist_show.style.display = "none";
login_show.style.display = "block";
login.style.borderBottom = "2px solid #b9def0"
regist.style.borderBottom = "none";
/* motai.style.display = "none";*/
welcome.innerHTML = "歡迎您、";
username.innerHTML = result.data;
});
}
}
})
}else {
validation_tip.innerText = "驗證碼輸入錯誤,請重新輸入"
}
}
};
算了,我把完整的js代碼貼上吧
window.onload=function () {
console.log("引用");
//模态頂部登陸注冊
var regist = document.querySelector(".regist-btn");
var login = document.querySelector('.login-btn');
//登陸注冊模态框主體
var regist_show = document.querySelector(".regist-show");
var login_show = document.querySelector(".login-show");
var phone_num = document.querySelector(".phone-num");//注冊時候手機号
var login_phone_num = document.querySelector(".login-phone-num");//登陸時号碼
var login_password = document.querySelector("#login-password");
var get_code = document.querySelector("#get-code");//擷取驗證碼按鈕
var pw = document.querySelector("#password");
var validation_tip = document.querySelector(".validation_tip");
var loging_tip = document.querySelector(".login-tips");//登陸的提示
var regist_mit = document.querySelector(".regist-mit"); //注冊按鈕
var login_mit = document.querySelector(".login-mit"); //登陸按鈕按鈕
var welcome = document.querySelector(".welcome"); //歡迎你
var username = document.querySelector(".username");
var motai = document.querySelector("#register") //擷取模态框
var phone_code = document.querySelector(".phone-code");//輸入驗證碼得值
var sms="";
var logout = document.querySelector("#logout");
/**
* 單擊登陸按鈕後的操作
*/
login_mit.onclick = function () {
console.log(login_phone_num.value);
console.log(login_password.value);
if (login_phone_num_verification()==true && login_password_verification()== true) {
console.log(44);
$.ajax({
url: "/btdev/user/login",
type : "post",
data:{
"telno" :login_phone_num.value,//将資料傳輸到伺服器
"pw":login_password.value
},
datatype:"json",
success:function (result) {
console.log(result.code);
if (result.code== 0 ) {
layer.msg("登入成功",{icon:1,time:1500,offset: '300px',shade: 0.3},function(){
console.log(result);
welcome.innerHTML = "歡迎您";
username.innerHTML = result.data.usersTelno;
/* motai.style.display = "none";*/
show_motai()
});
}else {
loging_tip.innerText = "沒有賬号 立即注冊?";
}
}
})
}
};
/**
* 登陸與注冊界面切換
*/
login.onclick = function () {
/* window.location.href="http://192.168.2.101:8081/btsy/user/login.html" target="_blank" rel="external nofollow" ;*/
console.log("login");
regist_show.style.display = "none";
login_show.style.display = "block";
login.style.borderBottom = "2px solid #b9def0"
regist.style.borderBottom = "none";
};
/**
* 登陸與注冊界面切換
*/
regist.onclick = function () {
console.log("regist");
regist_show.style.display = "block";
login_show.style.display = "none";
regist.style.borderBottom = "2px solid #b9def0";
login.style.borderBottom = "none"
};
/**
* 擷取驗證碼
*/
get_code.onclick = function () {
console.log(phone_num.value);
if (phone_num_verification() == true){
$.ajax({
url: "/btdev/user/getCode",
type: "POST",
data:{
"telno": phone_num.value
},
datatype: "json",
success:function (result) {
if(result.code==1){
console.log("可以注冊");
sms=result.data;
console.log(sms);
}else{
console.log("該手機号已經被注冊,請直接登入");
console.log(result.data);
validation_tip.innerText = result.data;
}
}
})
}
};
/**
* 單擊注冊按鈕後的操作
*/
regist_mit.onclick = function () {
password_verification();
console.log(sms);
console.log(phone_code.value);
console.log(phone_num.value);
console.log(pw.value);
if (phone_code.value==""){
validation_tip.innerText = "驗證碼不能為空"
} else {
if (password_verification()== true && (sms==phone_code.value) ) {
$.ajax({
url:"/btdev/user/regist",
type:"POST",
data:{
"telno" :phone_num.value,//将資料傳輸到伺服器
"pw":pw.value
},
datatyep:"json",
success:function (result) {
console.log("kk");
console.log(sms);
console.log(result.code);
console.log(result.data);
if (result.code==0){
layer.msg("注冊成功,正在前往登入界面",{icon:1,time:1500,offset: '300px',shade: 0.3},function(){
regist_show.style.display = "none";
login_show.style.display = "block";
login.style.borderBottom = "2px solid #b9def0"
regist.style.borderBottom = "none";
/* motai.style.display = "none";*/
welcome.innerHTML = "歡迎您、";
username.innerHTML = result.data;
});
}
}
})
}else {
validation_tip.innerText = "驗證碼輸入錯誤,請重新輸入"
}
}
};
/**
* 注冊時手機号驗證函數
* @returns {boolean}
*/
function phone_num_verification() {
var flag = false;
if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(phone_num.value)) {
validation_tip.innerText = "請輸入正确的手機号碼";
} else {
validation_tip.innerText = "";
flag = true;
}
return flag;
};
/**
* 登陸時手機号驗證函數
* @returns {boolean}
*/
function login_phone_num_verification() {
var flag = false;
if (!/^[1][3,4,5,7,8][0-9]{9}$/.test(login_phone_num.value)) {
loging_tip.innerText = "請輸入正确的手機号碼";
} else {
loging_tip.innerText = "";
flag = true;
}
return flag;
}
/**
* 注冊時候密碼驗證
* @returns {boolean}
*/
function password_verification() {
var flag = false;
if (!/^[a-zA-Z]\w{5,17}$/.test(pw.value)) {
validation_tip.innerText = "密碼長度在6~18之間,隻能包含字元、數字和下劃線";
} else {
validation_tip.innerText = "";
flag = true;
}
return flag;
};
/**
* 登陸時候密碼驗證
* @returns {boolean}
*/
function login_password_verification() {
var flag = false;
if (!/^[a-zA-Z]\w{5,17}$/.test(login_password.value)) {
loging_tip.innerText = "密碼長度在6~18之間,隻能包含字元、數字和下劃線";
} else {
loging_tip.innerText = "";
flag = true;
}
return flag;
}
/**
* 讓模态框内容消失
*/
function show_motai() {
console.log(222);
$("#register").modal('hide');//隐藏modal
/* motai.modal('hide');//隐藏modal*/
$('.modal-backdrop').remove();//去掉遮罩層
console.log("模态框消失");
}
/* /!**
* 單擊退出按鈕
*!/
$("#logout").click(function () {
//擷取目前頁面連接配接
var route = window.location.href;
console.log(route);
console.log("退出");
$.ajax({
url:"/btdev/user/logout",
type:"POST",
data:"",
datatype:"JSON",
success:function (data) {
window.location.replace(route)
}
})
})*/
}
整個過程就是 前端通過ajax把手機号傳到伺服器,伺服器首先要判斷手機号是否已經注冊,如果沒注冊就通過調用 AliyunSmsUtils.getTelnoCode(telno)方法将得到的驗證碼傳回前端。前端通過判斷使用者輸入的驗證碼和伺服器傳回的驗證碼是否一緻
整個過程就是 前端通過ajax把手機号傳到伺服器,伺服器首先要判斷手機号是否已經注冊,如果沒注冊就通過調用 AliyunSmsUtils.getTelnoCode(telno)方法将得到的驗證碼傳回前端。前端通過判斷使用者輸入的驗證碼和伺服器傳回的驗證碼是否一緻