config = config('InterfaceAPI.short_message'); $this->kmiConfig = config('InterfaceAPI.kmi_message'); $this->zrConfig = config('InterfaceAPI.zr_message'); $this->plantsConfig = config('InterfaceAPI.plant_message'); } public function send($phone, $ip, $UserID, $Content) { $model = new GamePhoneVerityCode(); // 生成验证码 $code = $this->code($phone); $content = urlencode(str_replace('{code}', $code, $Content)); $appKey = $this->config['appKey']; $password = $this->config['key']; $time = time(); $sign = md5($appKey . $password . $time); $data = [ 'appId' => $this->config['appId'], 'numbers' => $phone, 'content' => $content, 'senderId' => $code, ]; $model->addCode($UserID, $code, $phone, $ip); $build = http_build_query($data); Log::info('buka发送验证码参数 ' . $build); $gateway = $this->config['gateway'] . '?' . $build; $header = ['Sign' => $sign, 'Timestamp' =>$time, 'Api-Key' => $appKey]; Log::info('bukaheader-签名 ' . json_encode($header)."###".$appKey .'-'. $password .'-'. $time); $HttpCurl = new HttpCurl(); $res = $HttpCurl->curl_get($gateway, $header); Log::info('buka发送验证码结果:' . $res); try { $data = \GuzzleHttp\json_decode($res, true); }catch (\Exception $e){ $data=[]; } if (isset($data['status']) && $data['status'] == 0){ $this->setFrequent($ip, $phone,1); return true; } $this->error = ['web.verify.send_error','Falha ao obter o código de verificação']; return false; } public function zr_send($phone, $ip, $UserID, $Content) { $model = new GamePhoneVerityCode(); // 生成验证码 $code = $this->code($phone); $content = urlencode(str_replace('{code}', $code, $Content)); $accesskey = $this->zrConfig['accesskey']; $secret = $this->zrConfig['secret']; $time = time(); $data = [ 'accesskey' => $accesskey, 'secret' => $secret, 'mobile' => $phone, 'content' => $content, ]; $model->addCode($UserID, $code, $phone, $ip); $build = http_build_query($data); Log::info('zr发送验证码参数 ' . $build); $gateway = $this->zrConfig['gateway'] ; // $header = ['sign' => $sign, 'Timestamp' =>$time, 'Api-Key' => $appKey]; // Log::info('header-签名 ' . json_encode($header)."###".$appKey .'-'. $password .'-'. $time); $HttpCurl = new HttpCurl(); $res = $HttpCurl->curlPost($gateway, $build); Log::info('zr发送验证码结果:' . $res); $data = \GuzzleHttp\json_decode($res, true); if (isset($data['status']) && $data['status'] == 0){ $this->setFrequent($ip, $phone,2); return true; } $this->error = ['web.verify.send_error','Falha ao obter o código de verificação']; return false; } public function plants_send($phone, $ip, $UserID, $Content) { $model = new GamePhoneVerityCode(); // 生成验证码 $code = $this->code($phone); $content = urlencode(str_replace('{code}', $code, $Content)); $accesskey = $this->plantsConfig['appKey']; $secret = $this->plantsConfig['secretKey']; $time = time(); $data = [ 'appkey' => $accesskey, 'secretkey' => $secret, 'phone' => $phone, 'content' => $content, ]; $model->addCode($UserID, $code, $phone, $ip); $build = http_build_query($data); Log::info('plants发送验证码参数 ' . $build); $gateway = $this->plantsConfig['gateway'] ; // $header = ['sign' => $sign, 'Timestamp' =>$time, 'Api-Key' => $appKey]; // Log::info('header-签名 ' . json_encode($header)."###".$appKey .'-'. $password .'-'. $time); $HttpCurl = new HttpCurl(); $res = $HttpCurl->curlPost($gateway, $build); Log::info('plants发送验证码结果:' . $res); try { $data = \GuzzleHttp\json_decode(trim($res), true); if (isset($data['code']) && $data['code'] == 0) { $this->setFrequent($ip, $phone, 3); return true; } }catch (\Exception $exception){ if (strstr($res,'"code":"0"')) { $this->setFrequent($ip, $phone, 3); return true; } } $this->error = ['web.verify.send_error','Falha ao obter o código de verificação']; return false; } public function kmiSend($phone, $ip, $UserID, $Content) { $model = new GamePhoneVerityCode(); $code = $this->code($phone); $data = [ 'accessKey' => $this->kmiConfig['access_key'], 'secretKey' => $this->kmiConfig['secret_key'], //'from' => $content->TemplateID ?? '', 'to' => '0055' . $phone, 'message' => str_replace('{code}', $code, $Content), 'callbackUrl' => $this->kmiConfig['callbackUrl'] ]; Log::info('发送验证码参数 ' . \GuzzleHttp\json_encode($data)); $model->addCode($UserID, $code, $phone, $ip); $gateway = $this->kmiConfig['gateway']; $curl = new HttpCurl(); $res = $curl->curlPost($gateway, $data, 'json',true); Log::info('发送验证码结果:' . $res); $data = \GuzzleHttp\json_decode($res, true); if (isset($data['code']) && $data['code'] == 200) { $this->setFrequent($ip, $phone,4); return true; } $this->error = 'No se pudo obtener el código de verificación'; return false; } // 生成验证码 public function code($phone) { // 如果之前发送过验证码并且还没使用,还返回之前的验证码 $query = DB::connection('write')->table('QPTreasureDB.dbo.GamePhoneVerityCode') ->where('PhoneNum', $phone) ->first(); if ($query) return $query->Code; $length = $this->config['lengthNum'] ?: 4; $characters = '0123456789'; if (!is_int($length) || $length < 0) { return false; } $characters_length = strlen($characters) - 1;//因为字符串的顺序是从0开始的,下面的mt_rand()从0开始取,所以最后一个字符串要取到就只能减一 $string = ''; for ($i = $length; $i > 0; $i--) { $string .= $characters[mt_rand(0, $characters_length)]; } if ($string[0] == 0) $string[0] = mt_rand(1, 9); return $string; } // 验证码 public function sendVerify($phone, $ip, $Type, $Channel = 0) { $len = strlen($phone); // 验证手机号格式 if (str_starts_with($phone, '1')) { $len -= 1; if ($len < 9 || $len > 11) { Log::info('手机长度问题 ' . $len); $this->error = ['web.verify.phone_length_invalid', 'Sorry, mobile numbers with ' . $len . ' digits are not supported']; return false; } } $first = DB::connection('write')->table('QPAccountsDB.dbo.AccountPhone') ->where('PhoneNum', $phone) ->first(); // 注册发送验证码 -- 已经绑定过不允许发送 if ($Type == 0) { if ($first) { $this->error = ['web.verify.phone_already_bound', 'The phone number has already been bound']; return false; } } elseif ($Type == 1) { // 修改密码发送验证码 -- 判断手机号是否已经绑定 if (!$first) { $this->error = ['web.verify.account_not_exist', 'Failed to send code, account does not exist']; return false; } } $redis = Redis::connection(); // 限制IP一天发10次 if ($redis->get(self::IP_DAILY_LIMIT_PREFIX . $ip) >= self::FREQUENT_IP_LIMIT_NUM) { $this->error = ['web.verify.too_many_ip_requests', 'You have sent too many messages from this IP, sending is blocked']; return false; } // 同一个手机号发送次数不能超过5次 if ($redis->get(self::PHONE_DAILY_LIMIT_PREFIX . $phone) >= self::FREQUENT_PHONE_LIMIT_NUM) { $this->error = ['web.verify.too_many_phone_requests', 'You have sent too many messages from this phone number, sending is blocked']; return false; } // 发送间隔时间 if ($redis->exists(self::PHONE_FREQUENT_LIMIT_PREFIX . $phone . '_' . $Type)) { $this->error = ['web.verify.too_frequent_requests', 'You are sending too fast, please try again later']; return false; } return apiReturnSuc(); } /** * 设置频率 * @param string $ip * @param string $phone */ public function setFrequent($ip, $phone,$SendCodeConfigType) { Redis::set(self::PHONE_SEND_LASTCONFIG_PREFIX . $phone, $SendCodeConfigType); Redis::expire(self::PHONE_SEND_LASTCONFIG_PREFIX . $phone, 300); Redis::set(self::PHONE_FREQUENT_LIMIT_PREFIX . $phone, 1); Redis::expire(self::PHONE_FREQUENT_LIMIT_PREFIX . $phone, 118); Redis::incr(self::PHONE_DAILY_LIMIT_PREFIX . $phone); Redis::expireAt(self::PHONE_DAILY_LIMIT_PREFIX . $phone, strtotime('today +1 day')); Redis::incr(self::IP_DAILY_LIMIT_PREFIX . $ip); Redis::expireAt(self::IP_DAILY_LIMIT_PREFIX . $ip, strtotime('today +1 day')); } }