阿里云短信验证码实现

自己第一次做短信验证码,刚开始一直看阿里的文档,发现官方的文档真的是,,自己一直觉得短信验证码的接口不是很简单就可以调吗?官方怎么把它弄得这么复杂呀,,有点无语,还看见了有官方推荐的sdk,一个是github上面的,看了一下感觉不是很好用,还不如自己去找找有没有写得比较简单的sdk(因为发现调短信接口的签名生成还是挺麻烦的)。
在github上面看了一会,找到一个感觉还可以的(因为自己使用thinkphp开发的,刚好这个还挺适合的),在自己本地服务器上测试,一开始是自己没看清楚人家的代码,是要在自己的配置里面配置accessKeyId,accessKeySecret,templateCode,signName。对了,这些你们事先要去阿里上面申请好,不是很麻烦,就是模板审核(templateCode),还有短信签名(signName),还有两个称是AK值,。这些都是必填的。
后面一直去请求发送短信的接口,刚开始是报错是这样的:
阿里云短信验证码实现_第1张图片
这个是因为没有获取到配置里面的accessKeyId,所以报这个错了,在做这个之前一定要检查好这几个必要的参数没问题。
接着把这个问题解决好了又来了下一个问题:
阿里云短信验证码实现_第2张图片
或者是InvalidUserStstus.Malformed,遇到这种情况先检查自己的accessKeyId和
accessKeySecret有没有问题,如果没问题先给自己的账户里面充一点点钱进去(以免因为没有费用或者欠费导致失败),如果都没有问题,那就去检查确认一下accesskey是否添加了访问控制权限呢。
访问权限控制:https://help.aliyun.com/document_detail/108069.html?spm=a2c4g.11186623.6.599.2c0666faX6gLtN
不管有多个子用户还是主账户,你的accessKeySecret都是唯一的,最后添加了权限之后再试,发现又报错了(还是没成功,有点心累的感觉),这次报的是signaturedoesnotmatch,这个报错要么是因为有参数传错了,要么就是因为你的生成签名的算法有问题。
然后因为这个找了好几个小时,最后冷静下来想了一下,短信验证调一个接口,没有这么难啊,怎么自己还把它越弄越复杂了,最后明确下来,自己的sdk是两年前的了,而且还发现他请求的接口都不是和官方接口地址一样,最后决定放弃这一个sdk,找一个比较好用的应该就完事了,最后终于发现了比较好的可以用的。这里上代码:

 public function sendSms()
    {
        $mobile = Request::post('mobile');
        if (!preg_match('/^1[3|4|5|6|7|8|9]\d{9}$/', $mobile)) {
            $result['Code'] = '手机号格式不正确';
            return $result;
        }
        $code = rand(1000,999999);
        $config = config('sms.');
        // 获取配置信息
//        $config = $this->config['sms'];
        $accessKeyId = $config['accessKeyId']; // 阿里云 AccessKeyID
        $accessKeySecret = $config['accessKeySecret'];  // 阿里云 AccessKeySecret
        $templateCode = $config['templateCode'];   // 短信模板ID
        $signName=$config['signName'];   // 短信签名
        $params = array (
            'SignName' => $signName,
            'Format' => 'JSON',
            'Version' => '2017-05-25',
            'AccessKeyId' => $accessKeyId,
            'SignatureVersion' => '1.0',
            'SignatureMethod' => 'HMAC-SHA1',
            'SignatureNonce' => uniqid(),
            'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
            'Action' => 'SendSms',
            'TemplateCode' => $templateCode,
            'PhoneNumbers' => $mobile,
            // 营销短信无需 TemplateParam 参数
            'TemplateParam' => '{"code":"' . $code . '"}'
        );
        // 计算签名并把签名结果加入请求参数
        $params ['Signature'] = $this->computeSignature($params, $accessKeySecret);
        // 发送请求
        $url = 'http://dysmsapi.aliyuncs.com/?' . http_build_query($params);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $result = curl_exec($ch);
        curl_close($ch);
        //返回请求结果
        Session::set('code',$code);
        Session::set('create_time',time());
        $result = json_decode($result,true);
        return $result;
    }
     //短信签名计算
    protected function computeSignature($parameters, $accessKeySecret) {
        ksort($parameters);
        $canonicalizedQueryString = '';
        foreach ($parameters as $key => $value) {
            $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
        }
        $stringToSign = 'GET&%2F&' . $this->percentencode ( substr ( $canonicalizedQueryString, 1 ) );
        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
        return $signature;
    }
    protected function percentEncode($string) {
        $string = urlencode($string);
        $string = preg_replace('/\+/', '%20', $string);
        $string = preg_replace('/\*/', '%2A', $string);
        $string = preg_replace('/%7E/', '~', $string);
        return $string;
    }

写好的的两个方法简洁,不管放在什么框架里面也好用,单独写原生的也好用,用这个这个做测试刚开始也是报错signaturedoesnotmatch ,后面各种尝试,最后把子用户的accessKeyId换回成总账户的accessKeyId,再测就调用成功了,最后加在自己的项目里面,我自己是通过session来记录的。

github上面找sdk一定要找在最近才更新了的,这样会大大提高自己的成功率,也会节约你很多时间,调这个接口还花费了我一下午的时间才弄出来了,找对方法。

希望有遇到同样问题的小伙伴,可以对你们有帮助。

你可能感兴趣的:(php,API调用)