原文鏈接: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次,請明天請求!'); }