thinkphp+小程序手机短信验证码
前言
一、短信轰炸是什么?
短信轰炸一般基于 WEB 方式(基于客户端方式的原理与之类似),由两个模块组成,包括:一个前端 Web 网页,提供输入被攻击者手机号码的表单;一个后台攻击页面(如 PHP),利用从各个网站上找到的动态短信 URL 和 前端输入的被攻击者手机号码,发送 HTTP 请求,每次请求给用户发送一个动态短信。
- 被攻击者大量接收非自身请求的短信,造成无法正常使用移动运营商业务。
- 短信接口被刷通常指的就网站的动态短信发送接口被此类短信轰炸工具收集,作为其中一个发送途径
二、小程序准备
1.wxml
代码如下:
<view class="container">
<form bindsubmit="formSubmit" catchreset="formReset">
<view>
<view class="title">手机号</view>
<input type="text" name="phone" placeholder="请输入手机号" bindinput="send" bindblur="blur"/>
</view>
<view>
<view class="title">验证码</view>
<input type="text" name="code" style=" width: 200rpx;float: left;" placeholder="请输入密码" /> <span bindtap="sendcode" ><button class="send" size="mini" bindtap="countdown1" disabled="{{isDisabled}}" >{{title}}</button></span>
</view>
<view class="btn-area">
<button style="margin-top: 35rpx" type="primary" form-type="submit">登陆</button>
<button style="margin-top: 30rpx" formType="reset">重置</button>
</view>
</form>
</view>
2.wxss
代码如下:
/* pages/my/my.wxss */
.title{
font-size: 20px;
width: 500rpx;
text-align: center;
margin-top: 50rpx;
}
input{
margin-top: 20rpx;
width: 500rpx;
height: 50rpx;
text-align: center;
border: 1px solid #333333;
border-radius: 20rpx;
}
image{
width: 400rpx;
height: 400rpx;
}
.send{
margin-top: 20rpx;
margin-left: 20rpx;
}
3.js(使用小程序定时器限制)
/**
* 页面的初始数据
*/
data: {
title:"发送验证码", // 按钮中显示的字符
titleConst:"发送验证码", // 重置后的按钮中显示的字符
count:60, // 倒计时的秒数
countConst:60, // 重置后的倒计时的秒数
isDisabled:false // 按钮是否禁用
},
//失焦事件
blur(e){
// console.log(e.detail.value)
let value=e.detail.value;
//判断手机号不能为空
if(value==''){
//小程序提示信息
wx.showToast({
title: '请填写数据',
})
}
},
// setInterval中用箭头函数,保证this和外部一致
countdown: function(){
let count = this.data.count;
// 当count不为0开始倒计时,当count为0就关闭倒计时
// 设置定时器
var countdown = setInterval(() => {
if( count == 0 ){
//如果按钮未点击
//渲染data的初始数据
this.setData({
title:this.data.titleConst,
count: this.data.countConst,
isDisabled:false
});
// 取消定时器
clearInterval(countdown);
} else {
//如果按钮点击过
this.setData({
//替换按钮的数据
title:count-- + "s后重试",
//使按钮无法选中
isDisabled:true
});
}
//过期时间为1000
}, 1000);
},
// 用that保存this,防止在setInterval中this被替换
countdown1: function(){
let that = this;
let count = this.data.count;
// 当count不为0开始倒计时,当count为0就关闭倒计时
// 设置定时器
var countdown = setInterval(function(){
if( count == 0 ){
that.setData({
title:that.data.titleConst,
count: that.data.countConst,
isDisabled:false
});
// 取消定时器
clearInterval(countdown);
} else {
//把定时器的时间传输前端
that.setData({
title:count-- + "s后重试",
isDisabled:true
});
}
}, 1000);
},
//实时获取输入的手机号
send(e){
// console.log(e);
//把获取到的手机号渲染前端
this.setData({
phone:e.detail.value
})
},
//获取手机号
sendcode(){
let phone=[];
// console.log(this.data.phone)
//获取刚刚前端的渲染的手机号
phone=this.data.phone;
// console.log(phone);
//请求短信接口
wx.request({
url: 'http://www.fitness.com/demo/api/send',
data:{
phone:phone
},
success(res){
console.log(res.data);
}
})
},
formSubmit(e) {
console.log('form发生了submit事件,携带数据为:', e.detail.value);
let data= e.detail.value;
console.log(data)
wx.request({
url: 'http://www.fitness.com/demo/api/wxlogin',
method:'POST',
data:{
data:data
},
success(ret){
console.log(ret)
}
})
},
三、后台接口(ThinkPHP)
/**
* 小程序验证码(防止恶意调用)
*
* @param Request $request
* @return false|\think\response\Json
*/
public function send(Request $request)
{
$phone=$request->param();
//注 tp6不支持单个数据的验证 但是它适合批量数据的验证
$validate = \think\facade\Validate::rule([
'phone' => 'require|mobile',
]);
//验证参数
if (!$validate->check($phone)) {
die($validate->getError());
}
$phone=$phone['phone'];
if (Cache::has($phone)){
$time=Cache::get($phone);
$timenow = time();
if ($timenow-$time<60){
return json(['code'=>444,'msg'=>'一分钟内不可重复发送','data'=>[]]);
}
}
//生成四位随机验证码
$number=rand(1111,9999);
//手机号和点前发送时间存入缓存
$cache=Cache::set($phone,time(),60);
//验证码存入缓存
\cache('code',$number);
$bool=SendMessage::sendMsg($phone,$number);
print_r($cache);
if ($bool){
return json(['code'=>200,'msg'=>'发送成功']);
}
return json(['code'=>1001,'msg'=>'服务器繁忙!请稍后再试!']);
}