原文链接:https://blog.csdn.net/weixin_43389208/article/details/119153323
为什么使用短信:
场景:通常在使用手机号注册时需要发送短信验证码,在修改密码等敏感操作时也需要验证手机号发送短信验证码。
目的:验证用户的身份是否本人
平台:百度Apistore数据平台、聚合数据平台、京东万象等等。
在项目代码中发送短信,通常要调用第三方短信商的短信发送接口。
一般情况下,短信接口需要企业认证用户才能申请、一般都是收费的。个人可以购买使用。
思路:
1. 短信宝/京东万象等短信平台的短信api的账号开通及短信api接口申请。
短信宝官网 http://www.smsbao.com/
2. 下载php代码示例,在框架中实现短信接口开发。
实现:
1. 页面绑定验证码点击事件,并请求短信接口进行发送请求。
//验证码点击事件 $('#dyMobileButton').click(function () { var phone = $('#phone').val(); if (phone == '') { alert('手机号不能为空'); return false; } else if (!/^1[3-9]\d{9}$/.test(phone)) { alert('手机号规则不正确'); return false; } //短信发送限制 var time = 60; setInterval(function () { time--; if (time > 0) { //开始倒计时 $('#dyMobileButton').html('重新发送,还剩:' + time + '秒'); $('#dyMobileButton').prop('disabled', true); } else { //结束倒计时 $('#dyMobileButton').html('发送验证码'); $('#dyMobileButton').prop('disabled', false); } }, 1000); //请求短信接口 $.ajax({ 'url': 'http://www.1904a.com/sendMsg', 'type': 'POST', 'data': { sendPhone: phone }, 'datatype': 'json', 'success': function (res) { console.log(res); }, 'error': function (error) { console.log(error); return false; }, }); });
2. 将短信宝所需的配置文件信息存放在application/config下
//短信宝 'smsbao' => [ //短信宝api网址 'smsapi' => 'http://api.smsbao.com/', //你在短信宝注册的账号 'user' => '', //你在短信宝注册的密码 'pass' => '', ],
3. 请求短信发送的逻辑处理(短信宝密码需要进行md5加密)。
/** * 发送短信 * @return \think\response\Json */ public function sendMsg() { //接受参数 $post = input(); //验证参数 $validate = Loader::validate('User'); if (!$validate->scene('sendMsg')->check($post)) { $this->error($validate->getError(), 'home/login/register'); } //限制手机号次数 $redis = new Redis(); $num = $redis->inc('register_num_' . $post['sendPhone']); //key =>register_num_17807581416 value +1 if ($num > 10) { return getJsonData(10011, '手机号请求次数超过10次,请明天请求!'); } //限制验证码时间 $cacheTime = cache('register_time_' . $post['sendPhone']); if (time() - $cacheTime > 60 * 3) { return getJsonData(10012, '时间超过3分钟,请重新发送!'); } //限制ip $ip = request()->ip(); if ($ip != self::SERVER_IP) { return getJsonData(10013, 'ip地址不正确,无法发送短信,请检查ip'); } //获取短信宝配置信息 $smsbao = config('smsbao'); //随机数 $code = mt_rand(1000, 9999); //4023 $content = "【短信宝】您的验证码是" . $code . ",3分钟有效。";//要发送的短信内容 $sendurl = $smsbao['smsapi'] . "sms?u=" . $smsbao['user'] . "&p=" . md5($smsbao['pass']) . "&m=" . $post['sendPhone'] . "&c=" . urlencode($content); $result = file_get_contents($sendurl); if (!empty($result)) { //发送失败 return getJsonData(10010, $this->statusStr[$result]); } //缓存验证码,3分钟有效 cache('register_code_' . $post['sendPhone'], $code, 60 * 3); cache('register_code_' . $post['sendPhone'], time(), 60 * 3); $redis->set('register_num_' . $post['sendPhone'], 0, 60 * 60 * 24); return getJsonData(200, $this->statusStr[$result], $code); }
4:设置前端倒计时事件。
//设置倒计时 var time = 60; setInterval(function () { time--; if (time > 0) { //1分钟内 $("#dyMobileButton").prop('disabled', true); //按钮禁用 $("#dyMobileButton").html("重发验证码(" + time + ")"); //修改文案 } else { $("#dyMobileButton").prop('disabled', false); //按钮启用 $("#dyMobileButton").html("发送验证码"); //修改文案 } }, 1000);
延伸:
短信发送限制
1. 60秒内不可再次提交验证码。
方案:采用前端倒计时事件
2. 检测一定时间内的发送频率。(同一个手机号 一分钟只能发送一次)
//限制验证码时间 $cacheTime = cache('register_time_' . $post['sendPhone']); if (time() - $cacheTime > 60 * 3) { return getJsonData(10012, '时间超过3分钟,请重新发送!'); }
3. 限制用户ip地址。
const SERVER_IP = '127.0.0.1'; //限制ip $ip = request()->ip(); if ($ip != self::SERVER_IP) { return getJsonData(10013, 'ip地址不正确,无法发送短信,请检查ip'); }
4. 限制次数。(一个手机号一天只能请求10次)
//限制手机号次数 $redis = new Redis(); $num = $redis->inc('register_num_' . $post['sendPhone']); if ($num > 10) { return getJsonData(10011, '手机号请求次数超过10次,请明天请求!'); }