C# ASP.NET MVC 阿里云短信验证码Demo
相信大家在开发过程中又很多使用到验证码验证的功能,今天将验证码的验证整理一下写了一个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 onclick="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
下载地址