crmeb_pro 项目接入阿里云短信

crmeb_pro 框架内置了一个短信服务,但是根据群评价经常有人反馈不稳定,所以自行接入阿里云

文件地址 app\services\user\LoginService.php
找到 verify 函数,对比以下代码,把自己的配置改改即可使用
接入代码是通用的,什么项目都可以用,具体看这篇文章 阿里云短信API快速接入

<?php
    /**
     * 发送验证码
     * @param $phone
     * @param $type
     * @param $time
     * @param $ip
     * @return int
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function verify($phone, $type, $time, $ip)
    {
        if ($this->dao->getOne(['account' => $phone]) && $type == 'register') {
            throw new ValidateException('手机号已注册');
        }
        $default = Config::get('sms.default', 'yunxin');
        $defaultMaxPhoneCount = Config::get('sms.maxPhoneCount', 10);
        $defaultMaxIpCount = Config::get('sms.maxIpCount', 50);
        $maxPhoneCount = Config::get('sms.stores.' . $default . '.maxPhoneCount', $defaultMaxPhoneCount);
        $maxIpCount = Config::get('sms.stores.' . $default . '.maxIpCount', $defaultMaxIpCount);
        /** @var SmsRecordServices $smsRecord */
        $smsRecord = app()->make(SmsRecordServices::class);
        if ($smsRecord->count(['phone' => $phone, 'add_ip' => $ip, 'time' => 'today']) >= $maxPhoneCount) {
            throw new ValidateException('您今日发送得短信次数已经达到上限');
        }
        if ($smsRecord->count(['add_ip' => $ip, 'time' => 'today']) >= $maxIpCount) {
            throw new ValidateException('此IP今日发送次数已经达到上限');
        }

        /*-------------------------------------------------*/
        /**
        *
        *$phon 电话号码
        *$AccessKeyId 密钥
        *$accessKeySecret 密匙
        *$SignName 签名
        *$TemplateCode 模版id
        *$TemplateParam array 模版值
        *
        */
        function alisms($phone, $AccessKeyId, $accessKeySecret, $SignName, $TemplateCode, $TemplateParam, $domain = 'dysmsapi.aliyuncs.com') {
            $apiParams["PhoneNumbers"] = $phone; //手机号
            $apiParams["SignName"] = $SignName; //签名
            $apiParams["TemplateCode"] = $TemplateCode; //短信模版id
            $apiParams["TemplateParam"] = json_encode($TemplateParam);  //模版内容
            $apiParams["AccessKeyId"] = $AccessKeyId; //key
            $apiParams["RegionId"] = "cn-hangzhou"; //固定参数
            $apiParams["Format"] = "json";  //返回数据类型,支持xml,json
            $apiParams["SignatureMethod"] = "HMAC-SHA1"; //固定参数
            $apiParams["SignatureVersion"] = "1.0";  //固定参数
            $apiParams["SignatureNonce"] = uniqid(); //用于请求的防重放攻击,每次请求唯一
            date_default_timezone_set("GMT"); //设置时区
            $apiParams["Timestamp"] = date('Y-m-d\TH:i:s\Z'); //格式为:yyyy-MM-dd’T’HH:mm:ss’Z’;时区为:GMT
            $apiParams["Action"] = 'SendSms'; //api命名 固定子
            $apiParams["Version"] = '2017-05-25'; //api版本 固定值

            $apiParams["Signature"] = computeSignature($apiParams, $accessKeySecret);  //最终生成的签名结果值

            $requestUrl = "http://". $domain . "/?";

            foreach ($apiParams as $apiParamKey => $apiParamValue) {
                $requestUrl .= "$apiParamKey=" . urlencode($apiParamValue) . "&"; 
            }
            return curl(substr($requestUrl, 0, -1)); 
        }
        function computeSignature($parameters, $accessKeySecret) {
            ksort($parameters); 
            $canonicalizedQueryString = ''; 
            foreach ($parameters as $key => $value) {
                $canonicalizedQueryString .= '&' . percentEncode($key) . '=' . percentEncode($value); 
            }   
            $stringToSign = 'GET&%2F&' . percentencode(substr($canonicalizedQueryString, 1)); 
            $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . "&", true)); ; 

            return $signature; 
        }
        function percentEncode($str) {
            $res = urlencode($str); 
            $res = preg_replace('/\+/', '%20', $res); 
            $res = preg_replace('/\*/', '%2A', $res); 
            $res = preg_replace('/%7E/', '~', $res); 
            return $res; 
        }
        function curl($url)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); 
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_FAILONERROR, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $httpResponse=curl_exec($ch);
            if($httpResponse){
                return json_decode($httpResponse);

            }else{
                return json_decode(curl_error($ch));
            }
            curl_close($ch);
        }

        /*---------------------------------*/
        if (CacheService::get('code_' . $phone))
            throw new ValidateException($time . '分钟内有效');
        mt_srand();
        $code = rand(100000, 999999);
        $data['code'] = $code;
        $data['time'] = $time;
        $result = alisms($phone, 'LTAI5t9XXX', 'qGNG9FTCXXX', '只只云', 'SMS_66666', ['code' => $code]);
        if($result->Code == 'OK'){
            return $code;
        } else {
            throw new ValidateException('短信平台验证码发送失败');
        }
        // $res = SmsJob::dispatch([$phone, $data, 'VERIFICATION_CODE_TIME']);
        // if (!$res)
        //     throw new ValidateException('短信平台验证码发送失败');
        // return $code;
    }

当然,在这里处理的话是不如在任务队列处理更好的,如果用户量大还是放在队列处理,在任务队列处理的方式请看下一篇网站

给TA支持
共{{data.count}}人
人已支持
知道工作日志

阿里云短信API快速接入

2023-5-19 4:53:50

知道工作日志

完美解决 Recv failure: Connection was reset

2023-6-25 18:47:33

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索