周大胖子 发表于 2021-9-7 16:05:06

laravel 接 微信签名-

需求: 在微信公众号的网页里面 点击一下 调起导航 ,从而调起第三方APP腾讯或者百度的高德地图。
框架: laravel + easywechat + 微信公众号 网页开发模式

明确:
1.网页并不能在 微信中 直接打开第三方APP ,而是进入微信的地图页,由微信自己去调用 手机里的APP 。
2. 微信跳转 是需要微信签名的, 微信签名的获取,是一个前后台交互的过程。 前台负责传值[主要就是 openid 和 URL ],后端负责 处理,获取签名 然后再返回给前端. 前端形成配置项后使用。
3.URL 一定得是前端的URL,也就是你在哪个页面 使用微信的部分功能,就把当前页面的URL传递给后端 。

    /**
   * 微信签名获取
   */
    public function getSignature( Request $request )
    {
      // 先判断cache
      $jsapiTicket =$this->getTicket() ;
      
      $nonceStr = $this->createNonceStr();
      
      $timestamp = time();
      
      // var test = window.location.href; 这样就可以获取当前页面url,最近我写个微信功能也这样取的。[我的想法是前端的URL当前页,传给后台]
      // 签名用的url必须是调用JS接口页面的完整URL”
      // 注意 URL 一定要动态获取,不能 hardcode.
      $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
      // $url = "$protocol$_SERVER$_SERVER";
      $url = $request->input('url');
      
      // 这里参数的顺序要按照 key 值 ASCII 码升序排序
      $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
      
      $signature = sha1($string);

      $config = $this->sendConfig();
      
      // dd($config['app_id']);

      $signPackage = array(
          "appId"   => $config['app_id'],
          "nonceStr"=> $nonceStr,
          "timestamp" => $timestamp,
          "url"       => $url,
          "signature" => $signature,
          "rawString" => $string
      );
      return [
            'code'=>0,
            'message'=> '获取微信配置成功',
            'data'=>$signPackage
      ];
      // return $signPackage;

    }

    public function getTicket()
    {
      if(Cache::has('ticket')){

            return Cache::get('ticket');

      }else{
            
            $config = $this->sendConfig();

            $app = Factory::officialAccount($config);
   
            $accessToken = $app->access_token;
   
            $token = $accessToken->getToken(true); // 强制重新从微信服务器获取 token

            $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='. $token['access_token'].'&type=jsapi';
            
               //初始化
            $ticketArr = $this->curl_get($url);
            
            $ticket = $ticketArr['ticket'];

            Cache::put('ticket', $ticket ,now()->addMinutes(60));
      
            return $ticket;

      }
      
    }


    public function curl_get($url)
    {
       $headerArray =array("Content-type:application/json;","Accept:application/json");
      $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_HTTPHEADER,$headerArray);
      $output = curl_exec($ch);
      curl_close($ch);
      $output = json_decode($output,true);
      return $output;
    }
   
    /**
   *生成随机数
    */
   
    public function createNonceStr($length = 16) {
      $returnStr='';

      $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

      for($i = 0; $i < $length; $i ++) {
            
            $returnStr .= $pattern {mt_rand ( 0, 61 )};

      }
      return $returnStr;
    }
上面是后端PHP的。

下面是前端的内容
这里只放几个react 的 reducx 几个片段 ,大致就是发送当前的URL给PHP 之后 拿到返回数据 然后配置, 以及配置完之后在任意位置使用

export const actionGetWechatConf = (JsonDate) => ({
    type: GetWechatConf,
    value: JsonDate
})
export const funGetWechatConf = (value) => {


    let url = webServer + '/api/sd/get/wxc';
   
    return (dispatch) => {

      axios.get(url, {
            params: value,
            headers: {
                'token': localStorage.getItem('token')
            }
      }).then((res) => {
            let data = res.data;// 注意了 这里不能少一层
            checkRes(res.data);
            // 派发action
            dispatch(actionGetWechatConf(data));
      })
    }
}            Wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: allStore.weChatConf.appId, // 必填,公众号的唯一标识
                timestamp: allStore.weChatConf.timestamp, // 必填,生成签名的时间戳
                nonceStr: allStore.weChatConf.nonceStr, // 必填,生成签名的随机串
                signature: allStore.weChatConf.signature,// 必填,签名,见附录1
                jsApiList: [
                'openLocation',
                'onMenuShareTimeline'
                ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
            })

    // 点击打开微信位置功能
    gowechatAddress()
    {
      // if( !this.state.weChatConf){
      //   alert('系统提示', '地图初始化中请稍后点击', [
      //         { text: '我知道了', onPress: () => console.log('cancel'), style: 'default' },
      //   ]);
      //   return false;
      // }
      if(this.state.orderInfoData)
      {
            let s = this.state.orderInfoData;
            console.log(s.user_lat )
            console.log(s.user_lon )
            console.log(s.user_address )
            Wx.openLocation({
                latitude: s.user_lat, // 纬度,浮点数,范围为90 ~ -90
                longitude: s.user_lon, // 经度,浮点数,范围为180 ~ -180。
                name: s.user_address, // 位置名
                address: '客户所在位置', // 地址详情说明
                scale: 10, // 地图缩放级别,整形值,范围从1~28。默认为最大
            });
      }
      


    }





参考地址: 当时看了很多,谈不上有没有作用。 大部分都是参考下面的逻辑

        // http://www.jjyc.org/h/182281.html获取签名配置
    // https://blog.csdn.net/qq_40654664/article/details/90291509 获取签名配置
    // https://blog.csdn.net/weixin_34324081/article/details/88860591?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
    // https://blog.csdn.net/roamingcode/article/details/81773618触类旁通
    // https://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS-SDK%E6%8E%A5%E5%8F%A3微信接口文档
    // https://blog.csdn.net/dadsfasfadf/article/details/109443378   react实现微信分享
        // https://www.cnblogs.com/pxjbk/p/11823559.htmlPHP微信SDK经典运算
               




页: [1]
查看完整版本: laravel 接 微信签名-