相信大家在開發過程中又很多使用到驗證碼驗證的功能,今天將驗證碼的驗證整理一下寫了一個Demo
通過本篇後你能學習到:
- 阿里雲短信服務
- Drapper連接SQL Server進行增改操作
- JS前端倒計時
完成後效果如下:
(一)首先我們要使用短信我們先註冊短信服務所需的內容
1.首先阿里雲短信驗證碼首先打開阿里雲的短信服務網址
2.進入管理控制檯
在國內消息-簽名模板中添加一個簽名模板 簽名模板名稱這裏要記一下後面的開發中需要填入
3.簽名模板通過後我們需要再在國內消息模板管理裏面添加一個短信模板 同樣通過後 (模版CODE) 這個值在開發中需要填入
到這裏我們短信發送所需的內容就已經註冊好了接下來我們進行開發
(二)短信發送代碼開發
1.我們首先用vs創建一個MVC的項目
2.使用nuget引用aliyun第三方類庫如下圖所示:
3.由於使用驗證碼需要通過數據庫存儲我這裏使用了Drapper進行數據庫操作,Drapper的操作我們後面單獨用一篇文章來寫
這裏我就不詳細寫drapper引入的過程了
到這裏我們所需的程序依賴就已經引入完畢了
4.我們首先需要編寫一個發送短信的公共類來提供調用
阿里雲這裏提供了快速生成代碼的網址可以通過該網站填入內容快速生產代碼
其中需要注意的一個地方就是TemplateParam這裏我填的是
{"code":"你後臺生生成的驗證碼"}
這裏要和你申請的短信模板的內容相同比如你申請的是 ${code}
那麼TemplateParam 就是 {"code":"你後臺生成的驗證碼"}
如果申請的模板內容中帶多個參數的話請帶上多個json內容
將生產的代碼改了改如下所示:
static String product = "XXXX";//短信API產品名稱
static String domain = "dysmsapi.aliyuncs.com";//短信API產品域名
static String accessId = "XXXX";
static String accessSecret = "XXXX";
static String regionIdForPop = "cn-hangzhou";
//傳入手機號和驗證碼
public static CommonResponse SendMessage(string phone,string code)
{
CommonResponse response = new CommonResponse();
IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.Method = MethodType.POST;
request.Domain = domain;
request.Version = "2017-05-25";
request.Action = "SendSms";
// request.Protocol = ProtocolType.HTTP;
request.AddQueryParameters("PhoneNumbers", phone);
request.AddQueryParameters("SignName", product);
request.AddQueryParameters("TemplateCode", "xxxx");填入你模板管理中的模版CODE
request.AddQueryParameters("TemplateParam", "{\"code\":\"" + code + "\"}");
//驗證碼
try
{
response = client.GetCommonResponse(request);
return response;
}
catch (ServerException e)
{
Console.WriteLine(e);
return response;
}
catch (ClientException e)
{
Console.WriteLine(e);
return response;
}
}
其中有一個accessId和accessSecret獲取地址如下:
完成封裝過後開始前端和邏輯的處理
5.前端界面和代碼如下:
@{
ViewBag.Title = "短信發送";
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Pragma" content="no-cache">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<meta name="format-detection" content="telephone=yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>綁定信息</title>
<!-- Bootstrap core CSS-->
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.modal_content {
padding: 30px;
display: flex;
justify-content: center;
flex-direction: column;
}
.modal_content > div {
margin-bottom: 20px;
}
.modal_content > h5:first-child {
margin: 30px 0px;
}
#dialog label {
color: #666;
}
#phone {
display: block;
width: 100%;
height: 70px;
background: none;
padding-top: 30px;
border: 0;
outline: none;
text-align: center;
margin-top: -30px;
font-size: 16px;
border-bottom: 1px solid rgba(0,0,0,.2);
border-radius: 0;
}
.code {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
height: 70px;
background: none;
padding-top: 30px;
margin-top: -30px;
font-size: 16px;
border-bottom: 1px solid rgba(0,0,0,.2);
border-radius: 0;
}
#code {
width: calc(100% - 90px);
height: 55px;
background: none;
padding-top: 20px;
border: 0;
outline: none;
text-align: center;
margin-top: -20px;
font-size: 16px;
}
#btnSendCode {
width: 90px;
height: 30px;
padding: 0 5px;
margin: 0;
font-size: 14px;
text-align: center;
background: transparent;
border-radius: 30px;
color: #a07941;
border-color: #a07941;
}
::-webkit-input-placeholder { /* WebKit browsers */
font-size: 14px;
color: rgba(0,0,0,.4);
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
font-size: 14px;
color: rgba(0,0,0,.4);
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
font-size: 14px;
color: rgba(0,0,0,.4);
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
font-size: 14px;
color: rgba(0,0,0,.4);
}
.next {
text-align: center;
margin: 20px 0;
}
.next button {
width: 100%;
height: 45px;
padding: 0;
margin: 0;
background: #007BFF;
color: #fff;
border: 0;
outline: none;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="modal_content">
<h5>綁定用戶信息!</h5>
<div>
<label for="phone">註冊手機號:</label><br />
<input id="phone" type="text" autocomplete="off" placeholder="請輸入手機號" />
</div>
<div>
<label for="code">驗證碼:</label>
<div class="code">
<input id="code" type="text" autocomplete="off" placeholder="短信驗證碼" />
<input id="btnSendCode" type="button" class="btn btn-default" value="獲取驗證碼" onClick="sendMessage()" />
</div>
</div>
<div class="next">
<button οnclick="binding()">確定</button>
</div>
</div>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
var phoneReg = /(^1[3|4|5|7|8]\d{9}$)|(^09\d{8}$)/;//手機號正則
var count = 60; //間隔函數,1秒執行
var InterValObj1; //timer變量,控制時間
var curCount1;//當前剩餘秒數
/*第一*/
function sendMessage() {
curCount1 = count;
var phone = $.trim($('#phone').val());
if (!phoneReg.test(phone)) {
alert(" 請輸入有效的手機號碼");
return false;
}
//設置button效果,開始計時
$("#btnSendCode").attr("disabled", "true");
$("#btnSendCode").val(+ curCount1 + "秒再獲取");
InterValObj1 = window.setInterval(SetRemainTime1, 1000); //啓動計時器,1秒執行一次
//向後臺發送處理數據
var phone = $("#phone").val();
$.ajax({
type: "POST",
url: '/Home/SendSms',
data: { phone: phone },
dataType: "json",
success: function (data) {
if (data.success != true || data.success != "true") {
alert(data.Msg);
}
else {
alert("發送成功");
}
},
error: function (data) {
alert(data.Msg);
}
});
}
function SetRemainTime1() {
if (curCount1 == 0) {
window.clearInterval(InterValObj1);//停止計時器
$("#btnSendCode").removeAttr("disabled");//啓用按鈕
$("#btnSendCode").val("重新發送");
}
else {
curCount1--;
$("#btnSendCode").val(+ curCount1 + "秒再獲取");
}
}
/*提交*/
function binding() {
var phone = $("#phone").val();
var code = $("#code").val();
$.ajax({
type: "POST",
url: '/Home/VlidateCode',
data: { phone: phone, code: code },
dataType: "json",
success: function (data) {
alert(data.Msg);
},
error: function (data) {
alert(data.Msg);
}
});
}
</script>
</body>
</html>
6.後臺代碼:
(1)發送短信數據庫如下所示
內容包含id,手機號,發送時間,是否失效,和驗證碼
(2)後臺代碼
發送短信前需要先查詢發送短信時間是否過短
然後發送驗證碼成功後要將之前同一個手機發送過的驗證碼修改位失效狀態
查詢驗證碼的時候也得和驗證碼的有效時間一致過期了就提示重新發送短信
/// <summary>
/// 寫入一條短信信息
/// </summary>
/// <param name="person">用戶信息實體</param>
/// <returns></returns>
public bool Insert(Sms sms)
{
using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString))
{
string sql = "INSERT INTO Sms(phone, AddDate, Code) VALUES(@phone, @AddDate, @Code)";
int result = db.Execute(sql, sms);
return result > 0; //簡化的轉換寫法
}
}
/// <summary>
/// 根據手機號查詢
/// </summary>
/// <param name="Phone">手機號</param>
/// <returns></returns>
public Sms FindByPhone(string Phone)
{
using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString))
{
DateTime Datimehours = DateTime.Now.AddMinutes(-30);
string sql = $"SELECT * FROM Sms WHERE phone=@phone and IsDeleted=0 and adddate>@Datimehours";
IEnumerable<Sms> list = db.Query<Sms>(sql, new { phone = Phone , Datimehours= Datimehours });
return list.FirstOrDefault();
}
}
/// <summary>
/// 根據查詢最近一次的手機號驗證碼判斷是否大於60s用於判斷是否發送時間間隔過短
/// </summary>
/// <param name="Phone">手機號</param>
/// <returns></returns>
public Boolean IsSoShort(string phone)
{
Boolean SoShort = false;
using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString))
{
string sql = $"SELECT * FROM Sms WHERE phone=@phone";
List<Sms> sms = db.Query<Sms>(sql, new { phone = phone }).OrderByDescending(t=>t.AddDate).ToList();//查詢最近一次的手機號驗證碼
//如果查詢條數大於0
if (sms.Count > 0)
{
Sms LastSms = sms.FirstOrDefault();
DateTime Now = DateTime.Now;
DateTime SendTime = LastSms.AddDate;
TimeSpan ts = Now.Subtract(SendTime);
int sec = (int)ts.TotalSeconds;
if (sec < 60)
{
SoShort = true;
}
}
return SoShort;
}
}
/// <summary>
/// 更新一條用戶數據
/// </summary>
/// <param name="person">用戶信息實體</param>
/// <returns></returns>
public bool Updatephone(string phone)
{
using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString))
{
string sql =
"UPDATE Sms SET IsDeleted = 1 WHERE phone = @phone";
int result = db.Execute(sql, new { phone = phone });
return result > 0; //簡化的轉換寫法
}
}
public JsonResult SendSms(string phone)
{
SendSmsResponse Smsresponse = new SendSmsResponse();
SmsSendService sendserver = new SmsSendService();
Boolean isshort = sendserver.IsSoShort(phone);
if (isshort)
{
return Json(new
{
success = false,
Msg = "發送短信間隔過短請勿重複發送",
data = ""
});
}
//生成6位隨機驗證碼
string code = SendSmsHepler.Number(6);
try
{
CommonResponse smsend = SendSmsHepler.SendMessage(phone, code);
Smsresponse=JsonConvert.DeserializeObject<SendSmsResponse>(smsend.Data);
}
catch (Exception e)
{
return Json(new
{
success = false,
Msg = e.Message,
data = ""
});
}
//如果發送成功
if (Smsresponse.Code != null && Smsresponse.Code == "OK")
{
Sms sms = new Sms();
sms.phone = phone;
sms.Code = code;
sms.AddDate = DateTime.Now;
//修改之前發送短信爲失效狀態
bool upphone = sendserver.Updatephone(phone);
//將新短信內容插入數據庫
var success = sendserver.Insert(sms);
return Json(new
{
success = true,
Msg = "成功",
data = ""
});
}
else
{
return Json(new
{
success = false,
Msg = Smsresponse.Message,
data = ""
});
}
}
public JsonResult VlidateCode(string phone,string code)
{
SendSmsResponse Smsresponse = new SendSmsResponse();
SmsSendService sendserver = new SmsSendService();
Sms sms = sendserver.FindByPhone(phone);
if (sms != null && sms.id>0)
{
if (sms.Code == code)
{
bool upphone = sendserver.Updatephone(phone);
return Json(new
{
success = true,
Msg = "驗證成功",
data = ""
});
}
else
{
return Json(new
{
success = false,
Msg = "驗證失敗",
data = ""
});
}
}
else
{
return Json(new
{
success = false,
Msg = "請先發送短信",
data = ""
});
}
}
最後需要源碼都請掃碼關注回覆:短信Demo
獲取下載地址