| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- <?php
- namespace App\Http\logic\api;
- use App\Http\helper\HttpCurl;
- use App\Models\GamePhoneVerityCode;
- use App\Util;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Redis;
- class SendCodeLogic extends BaseApiLogic
- {
- const IP_DAILY_LIMIT_PREFIX = 'ip_daily_limit_';
- const PHONE_DAILY_LIMIT_PREFIX = 'phone_daily_limit_';
- /** @var string 每分钟频率限制key前缀 */
- const PHONE_FREQUENT_LIMIT_PREFIX = 'phone_frequent_limit_';
- const PHONE_SEND_LASTCONFIG_PREFIX = 'phone_send_last_';
- const FREQUENT_IP_LIMIT_NUM = 20;
- const FREQUENT_PHONE_LIMIT_NUM = 10;
- protected $config; // 天一宏 -- 不卡
- protected $kmiConfig; // kmi
- protected $zrConfig; // ZhangRong
- protected $plantsConfig; // ZhangRong
- public function __construct()
- {
- // 天一宏 -- 不卡
- $this->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)
- {
- $first = DB::connection('write')->table('QPAccountsDB.dbo.AccountPhone')
- ->where('PhoneNum', $phone)
- ->where('Channel', $Channel)
- ->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'));
- }
- }
|