阿里云发送短信与验证码

阿里云短信发送流程

第一步 使用composer 下载阿里大鱼短信接口

 composer require flc/dysms

第二步 使用下载好的文件 在控制器中进行引用

use Flc\Dysms\Client;
use Flc\Dysms\Request\SendSms;

第三步  正式使用 在你需要用到方法当中

设置短信的key和secret

$config = [
    'accessKeyId'    => $this->sms_appid,
    'accessKeySecret' => $this->sms_sercert,
];

完整后端

public function sendsms(Request $request){
       
            $phone=$request->input('phone');
            if($phone){
                if(!preg_match("/^((13[0-9])|(15[^4])|(16[5,6])|(17[0-8])|(18[0-9])|(19[0,1,3,5,6,8-9])|(14[4,5,7])|(156))\d{8}$/",$phone)){
                    
        		    return ['code'=>404,'msg'=>'手机格式不正确,请换手机号尝试']; 
        		    exit;
        		}
            }else{
                return ['code'=>404,'msg'=>'请填写手机号']; 
    		    exit;
            }
            
            
            if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false) {
                // return 1;
                // $ip=$this->getip();
                //简单监控限制不可超过十五次
                $i=session('i');
                if(!$i)$i=0;
                if($i<15){
                    $i++;
                    session(['i'=>$i]);
                }else{
                    return ['code'=>404,'msg'=>'您的活动行为异常!!'];
                    exit;
                }
                
            } 
    
            
            $config = [
                'accessKeyId'    => 'LTAI4GHx2DHakq7ZBDgKZpBC',
                'accessKeySecret' => '8RwbqCJU4zhJ0XZ1DMeu7RmozmLOw2',
            ];
            $client  = new Client($config);
            $sendSms = new SendSms;
            $sendSms->setPhoneNumbers($phone);
            $sendSms->setSignName('荣德基官网');
            $sendSms->setTemplateCode('SMS_129395050');
            $code=rand(100000, 999999);
            $sendSms->setTemplateParam(['code' => $code]);
            $client->execute($sendSms);
            session(['code'=>$code]);
            session(['phone'=>$phone]);
        
    }

前端

	<div>收件手机:	<input type="number" placeholder="" name="phone" class="phone" ><input type="button" id="btn" maxlength="11" value="获取验证码">/div>
	<div>短信验证:<input type="number"></div>

<script>
function settime(obj){
            if(countdown==0){
                obj.attr('disabled',false);
                obj.css('background','#eb8c6a');
                obj.val('获取验证码');
                countdown = $(".yzmtime").val();
                return;
            }else{
                obj.attr('disabled',true);
                obj.css('background','#e1a985');
                obj.val("验证码(" + countdown + ")");
                countdown--;
            }
            setTimeout(function(){settime(obj);},1000)
        }
        
        if($(".bt").val()==2){
             var obj = $("#btn");
             settime(obj);
        }

 $('.sj-code').click(function(){
            phone=$(".phone").val();
            rep=/^((13[0-9])|(15[^4])|(16[5,6])|(17[0-8])|(18[0-9])|(19[0,1,3,5,8-9])|(14[4,5,7])|(156))\d{8}$/;
            if(!phone){
                
                layer.msg("请填写手机号", { icon: 7, time: 3000, shade: [0.6, '#000', true] });
                return false;
            }else if(!rep.test(phone)){
                layer.msg("手机号格式不正确", { icon: 7, time: 3000, shade: [0.6, '#000', true] });
                return false;
            }
            var obj = $("#btn");
            
           
            settime(obj);
            var url="/sendsms";
            
            
            $.post(url, {phone:phone}, function (data) {
                if(data.code==404){
        		    layer.msg(data.msg, { icon: 7, time: 3000, shade: [0.6, '#000', true] });
        		    return false;
        		}
			});
           
        });
</script>

效果图

优化

短信发送如果不做限制很容易被机器刷,所以需要加入图片验证码,验证成功后发送短信

可结合阿里云验证码功能实现

PHP接入

composer requrie alibabacloud/captcha-20230305

后端

引入

use Flc\Dysms\Client;
use Flc\Dysms\Request\SendSms;
use AlibabaCloud\SDK\Captcha\V20230305\Captcha;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;
public static function createClient(){
        // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
        // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/311677.html。
        $config = new Config([
            // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
            'accessKeyId'    => 'xxx',
            // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
             'accessKeySecret' => 'xxx',
        ]);
        // Endpoint 请参考 https://api.aliyun.com/product/captcha
        $config->endpoint = "captcha.cn-shanghai.aliyuncs.com";
        return new Captcha($config);
    }
    public function sendsms(Request $request){
        $captchaVerifyParam=$request->input('captchaVerifyParam');
        $client = self::createClient();
        $verifyCaptchaRequest = new VerifyCaptchaRequest([
            "captchaVerifyParam" => $captchaVerifyParam
        ]);
        try {
            // echo("<pre>");
            // 复制代码运行请自行打印 API 的返回值
            $result=$client->verifyCaptchaWithOptions($verifyCaptchaRequest, new RuntimeOptions([]));
            
            if($result->body->result->verifyResult){
                $phone=$request->input('phone');
                if($phone){
                    if(!preg_match("/^((13[0-9])|(15[^4])|(16[5,6])|(17[0-8])|(18[0-9])|(19[0,1,3,5,6,8-9])|(14[4,5,7])|(156))\d{8}$/",$phone)){
                        
            		    return ['code'=>404,'msg'=>'手机格式不正确,请换手机号尝试']; 
            		    exit;
            		}
                }else{
                    return ['code'=>404,'msg'=>'请填写手机号']; 
        		    exit;
                }
                
                
                if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false) {
                    // return 1;
                    // $ip=$this->getip();
                    //简单监控限制不可超过十五次
                    $i=session('i');
                    if(!$i)$i=0;
                    if($i<15){
                        $i++;
                        session(['i'=>$i]);
                    }else{
                        return ['code'=>404,'msg'=>'您的活动行为异常!!'];
                        exit;
                    }
                    
                } 
        
                
                $config = [
                    'accessKeyId'    => 'LTAI4GHx2DHakq7ZBDgKZpBC',
                    'accessKeySecret' => '8RwbqCJU4zhJ0XZ1DMeu7RmozmLOw2',
                ];
                $client  = new Client($config);
                $sendSms = new SendSms;
                $sendSms->setPhoneNumbers($phone);
                $sendSms->setSignName('荣德基官网');
                $sendSms->setTemplateCode('SMS_129395050');
                $code=rand(100000, 999999);
                $sendSms->setTemplateParam(['code' => $code]);
                $client->execute($sendSms);
                session(['code'=>$code]);
                session(['phone'=>$phone]);
                session(['time'=>time()]);
            }
            
            return json_encode($result);
          
        }
        catch (Exception $error) {
            if (!($error instanceof TeaError)) {
                $error = new TeaError([], $error->getMessage(), $error->getCode(), $error);
            }
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            var_dump($error->message);
            // 诊断地址
            var_dump($error->data["Recommend"]);
            Utils::assertAsString($error->message);
        }
        
        
    }

前端



<div>收件手机:	<input type="number" placeholder="" name="phone" class="phone" ><input type="button" id="btn" maxlength="11" value="获取验证码">/div>
	<div>短信验证:<input type="number"></div>
<script type="text/javascript" src="https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js"></script>
<script>
var countdown=60;
        var obj = $("#btn");
         
            let captcha;
          // 弹出式
          initAliyunCaptcha({
            SceneId: 'xxx', // 场景ID。根据步骤二新建验证场景后,您可以在验证码场景列表,获取该场景的场景ID
            prefix: 'xxx', // 身份标。开通阿里云验证码2.0后,您可以在控制台概览页面的实例基本信息卡片区域,获取身份标
            mode: 'popup', // 验证码模式。popup表示要集成的验证码模式为弹出式。无需修改
            element: '#captcha-element', //页面上预留的渲染验证码的元素,与原代码中预留的页面元素保持一致。
            button: '#btn', // 触发验证码弹窗的元素。button表示单击登录按钮后,触发captchaVerifyCallback函数。您可以根据实际使用的元素修改element的值
            captchaVerifyCallback: captchaVerifyCallback, // 业务请求(带验证码校验)回调函数,无需修改
            onBizResultCallback: onBizResultCallback, // 业务请求结果回调函数,无需修改
            getInstance: getInstance, // 绑定验证码实例函数,无需修改
            slideStyle: {
              width: 360,
              height: 40,
            }, // 滑块验证码样式,支持自定义宽度和高度,单位为px。其中,width最小值为320 px
            language: 'cn', // 验证码语言类型,支持简体中文(cn)、繁体中文(tw)、英文(en)
            region: 'cn' //验证码示例所属地区,支持中国内地(cn)、新加坡(sgp)
          });
        
          // 绑定验证码实例函数。该函数为固定写法,无需修改
          function getInstance(instance) {
            captcha = instance;
          }
        
         
    async function captchaVerifyCallback(captchaVerifyParam) {
            phone=$(".phone").val();
            rep=/^((13[0-9])|(15[^4])|(16[5,6])|(17[0-8])|(18[0-9])|(19[0,1,3,5,6,8-9])|(14[4,5,7])|(156))\d{8}$/;
            if(!phone){
                
                layer.msg("请填写手机号", { icon: 7, time: 3000, shade: [0.6, '#000', true] });
                return false;
            }else if(!rep.test(phone)){
                layer.msg("手机号格式不正确", { icon: 7, time: 3000, shade: [0.6, '#000', true] });
                return false;
            }
         const response = await fetch('https://active.rongdeji.com/sendsms', {
                method: 'POST',
                mode: 'cors',
                cache: 'no-cache',
                credentials: 'same-origin',
                headers: {
                  'Content-Type': 'application/json'
                },
                redirect: 'follow',
                referrerPolicy: 'no-referrer',
                body:  JSON.stringify({captchaVerifyParam:captchaVerifyParam,phone:phone})
              });
                    
         
              
              const data = await response.json();
            //   console.log(data.body.result.verifyResult);
                        const verifyResult = {
                          captchaResult: data.body.result.verifyResult, // 验证码验证是否通过,boolean类型,必选
                          bizResult: data.body.result.verifyResult, // 业务验证是否通过,boolean类型,可选;若为无业务验证结果的场景,bizResult可以为空
                        };
                        return verifyResult;
            }
          // 业务请求验证结果回调函数
          function onBizResultCallback(bizResult) {
            //  console.log(78157)
            if (bizResult === true) {
                 var obj = $("#btn");
                 settime(obj);
            } else {
              // 如果业务验证不通过,给出不通过提示。此处不通过提示为业务验证不通过!
            //   alert('业务验证不通过!');
                layer.msg("操作异常", { icon: 7, time: 3000, shade: [0.6, '#000', true] });
                return false;
            }
          }
function settime(obj){
            if(countdown==0){
                obj.attr('disabled',false);
                obj.css('background','#eb8c6a');
                obj.val('获取验证码');
                countdown = $(".yzmtime").val();
                return;
            }else{
                obj.attr('disabled',true);
                obj.css('background','#e1a985');
                obj.val("验证码(" + countdown + ")");
                countdown--;
            }
            setTimeout(function(){settime(obj);},1000)
        }
        
        if($(".bt").val()==2){
             var obj = $("#btn");
             settime(obj);
        }


</script>

效果图(以拼图验证为例)