zoukankan      html  css  js  c++  java
  • php 微信JS-SDK封装类

    JSSDK使用步骤:

    步骤一:绑定域名

    步骤二:引入JS文件

    步骤三:通过config接口注入权限验证配置

    步骤四:通过ready接口处理成功验证

    步骤五:通过error接口处理失败验证

    具体步骤方法说明给查看官方给出的微信开发者文档

    https://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html

    所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用

    wx.config({
    
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    
        appId: '', // 必填,公众号的唯一标识
    
        timestamp: , // 必填,生成签名的时间戳
    
        nonceStr: '', // 必填,生成签名的随机串
    
        signature: '',// 必填,签名
    
        jsApiList: [] // 必填,需要使用的JS接口列表
    
    });

    其中要保证能正常使用接口的一个重要条件就是获取签名,那么签名是什么,有什么用,怎么获取签名就是今天我今天要讲的重点了。

    签名,在我们日常生活中经常用到,在一些核实、审查信息,结案等时候需要某个人的亲笔签名,在网站开发中也一样,签名是否正确是能否调用微信接口的重要条件,可以理解为就是票据。

    签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。


    即signature=sha1(string1)。 示例:

    • noncestr=Wm3WZYTPz0wzccnW
    • jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
    • timestamp=1414587457
    • url=http://mp.weixin.qq.com?params=value


    步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
    


    对string1进行sha1签名,得到signature:

    0f9de62fce790f9a083d5c99e95740ceb90c27ed
    好了 我们已经看到了 获得签名需要4个参数,其中timestamp时间戳和url页面完整url都很容易获得,现在就需要获得noncestr随机字符串和jsapi_ticket。
    生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取.
    好了说了这么多 我们直接来看一段代码实例:


    class jsControl{
        //$store_id是店铺id用来去数据库中查询这个店铺当前的微信公众号信息,appid,appsecret等信息
    /**
    *@param int $store_id 店铺id用于到数据库中获取店铺微信公众号的配置信息
    *@return  返回config接口注入权限验证配置信息
    **/
      public function getJsConfigInfo($store_id = 0){
        if(!$this->checkIsInWeixin()){
            return [];
        }
        if(!$store_id){
            $store_id = intval($_SESSION['store_member_info_ID'] ?: ($_SESSION['route_store_id'] ?: ($_GET['store_id'] ?: $_SESSION['store_id'])));
        }
        if(empty($store_id)){
            return [];
        }
        $store_info  = Model()->table('store_wxinfo')->where(['store_id' => $store_id])->find();//查询店铺公众号配置信息
        if(empty($store_info)){
            return [];
        }
        $tickets = $this->get_jsapi_ticket($store_info['store_id'], $store_info['appid'], $store_info['appsecret']);
        if(empty($tickets)){
            return [];
        }
        $nonceStr = $this->getNonceStr();
        $timestamp = TIMESTAMP;
        $url = $this->getSelfLink();
        $string1    = "jsapi_ticket={$tickets}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
        $signature  = sha1($string1);
        return [
            'debug' => false,
            'appId' => $store_info['appid'],
            'timestamp' => $timestamp,
            'nonceStr' => $nonceStr,
            'signature' => $signature,
            'jsApiList' => ['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone','startRecord','stopRecord','onVoiceRecordEnd','playVoice','pauseVoice','stopVoice','onVoicePlayEnd','uploadVoice','downloadVoice','chooseImage','previewImage','uploadImage','downloadImage','translateVoice','getNetworkType','openLocation','getLocation','hideOptionMenu','showOptionMenu','hideMenuItems','showMenuItems','hideAllNonBaseMenuItem','showAllNonBaseMenuItem','closeWindow','scanQRCode','chooseWXPay','openProductSpecificView','addCard','chooseCard','openCard']
        ];
       }
    
    
       public function getSelfLink(){
        $protocol   = strpos(strtolower($_SERVER['SERVER_PROTOCOL']), 'https') !== false ? 'https://' : 'http://';
        $host       = $protocol . $_SERVER['HTTP_HOST'];
        $url        = $host . $_SERVER['REQUEST_URI'];
        return $url;
       }
       public function getNonceStr(){
            $chars  = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            $str    = '';
            for ($i = 0; $i < 16; $i++) {
                $str .= $chars{mt_rand(0, strlen($chars) - 1)};
            }
            return $str;
       }
       public function _get_access_token($store_id,$appid,$appsecret){
            $token = rkcache("access_token_$store_id");
            if(!empty($token)){
                $token = unserialize($token);
            }else{
                $token = array();
            }
            if(empty($token) || time()-$token['create_time'] > 7200){
                $uri   = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
                $token = curl($uri);
                $token = json_decode($token,true);
                if(!isset($token['access_token']) || empty($token['access_token'])){
                    return '';
                }
                $token['create_time']=time();
                wkcache("access_token_$store_id",serialize($token));
            }
            return $token['access_token'];
        }
        function get_jsapi_ticket($store_id,$appid,$appsecret) {
            $tickets = rkcache("jsapi_ticket_$store_id");
            if ($tickets) {
                $tickets = unserialize($tickets);
            }
            if (empty($tickets) || time() - $tickets['create_time'] >= 7200) {
                $access_token = $this->_get_access_token($store_id,$appid,$appsecret);
                if ('' == $access_token) {
                    return '';
                }
                $uri     = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $access_token . '&type=jsapi';
                $tickets = curl($uri);
                $tickets = json_decode($tickets, true);
                if (empty($tickets['ticket'])) {
                    return '';
                }
                $tickets['create_time'] = time();
                wkcache("jsapi_ticket_$store_id", serialize($tickets));
            }
            return $tickets['ticket'];
        }
    
       protected function checkIsInWeixin() {
          if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
             return true;
          }
          return false;
       }
    
    }

    给出一个前端js调用的方法:

    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script type="javascript/text" > 
    
    var wx_data = <?php echo json_encode($output['jsapi_config']); ?>;
        var member_info = <?php echo json_encode($output['member_info']);?>;
        var goods_img = $("#goods_img").find("img").attr("src");
        wx.config(wx_data);
        if($.isEmptyObject(wx_data.appId)){
            alert('请在微信中打开分享');
        }
        var sharedata = {
            title    : "<?php  echo $output['goods_info'][0]['goods_name'];?>",
            desc     :'你的朋友:' + member_info.member_name + ' 给你分享了好商品,快来看看吧',
            imgUrl   : goods_img,
            link     :"<?php echo $output['link_url']; ?>",
            success: function(){
            },
            cancel: function(){
            }
        };
        wx.ready(function () {
            wx.onMenuShareAppMessage(sharedata);
            wx.onMenuShareTimeline(sharedata);
        });
    </script>

    总结一下:

    通过config接口注入权限验证配置:

    var config_info = {};

    config_info对象中需要的属性有5个 :
    1获取qppid,2获取生成签名的时间戳(timestamp),3获取生成签名的随机字符串(noncestr),4获取签名(signature),5调动的接口列表。


    其中获取签名需要4个参数:1随机字符串noncestr,2时间戳(timestamp),3调用票据jsapi_ticket,4当前页面完整url


    其中获取调用票据jsapi_ticket需要一个携带access_token的请求获取:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

    所以完整的流程就是:库中查询appid,appsecret,然后获取access_token,通过access_token获取票据jsapi_ticket,得到票据jsapi_ticket后生成签名,然后完成全线验证配置

     

    原创作品,转载请注明出处!

  • 相关阅读:
    GitLab备份与恢复
    内网穿透frp
    Python Day21-22(Django进阶)
    Python Day19-20(Django基础)
    Python Day18(Django初识)
    Python Day17(jQuery)
    Python day16(JavaScript)
    Python Day15(CSS)
    Unity组件
    关于游戏
  • 原文地址:https://www.cnblogs.com/imnzq/p/6811438.html
Copyright © 2011-2022 走看看