• 微信第三方授权


    前段时间做了一个微信第三方授权,一直想写一篇文章分享一下,但是总是忙,今天终于有空闲给写出来了,整个流程很简单清晰,在签名验证的地方可能有点儿小坑,并且在用户取消授权的时候,微信api说的是会把消息推送到回调地址中,在这里强调一下这个回调地址不是授权时候的回调地址,而是你申请第三方平台时候填写的授权地址,闲话少说进入正题。(如有问题,可留言交流)

    简单流程先描述

      用户点击授权按钮 -> 获取第三方令牌 -> 获取预授权码 -> 进入微信授权页面 -> 用户扫码授权 -> 微信推送授权结果

    第一步 维护微信推送的 component_verify_ticket

      在第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket,该ticket是加密的xml串,需要解码获取到ticket值(用于获取预授权码);

      解密用的是php的加解密模块(安装php自带的),代码用的是微信提供的。

      代码如下

         $timeStamp  = empty($_GET['timestamp']) ? "" : trim($_GET['timestamp']); // 时间戳
            $nonce      = empty($_GET['nonce']) ? "" : trim($_GET['nonce']); // 随机字符
            $msg_sign   = empty($_GET['msg_signature']) ? "" : trim($_GET['msg_signature']); // 签名(公钥)
            $encryptMsg = file_get_contents('php://input'); // xml
    
            $xml_tree = new DOMDocument();
            $xml_tree->loadXML($encryptMsg);
            $array_e = $xml_tree->getElementsByTagName('Encrypt');
            $encrypt = $array_e->item(0)->nodeValue;
            $format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
            $from_xml = sprintf($format, $encrypt);
    
            // 第三方收到公众号平台发送的消息
            $weixinConfig = Config::get('weixin');
            $appId = $weixinConfig['app_id'];
            $appKey = $weixinConfig['app_key'];
            $appToken = $weixinConfig['app_token'];
    
            $msg = '';
            $pc = new WXBizMsgCrypt( $appToken, $appKey, $appId );
            $errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg);
    
            // 解密失败
            if ( $errCode != 0 ) {
                echo'error';
                return;
            }
    
            $xml = new DOMDocument();
            $xml->loadXML($msg);
            $array_auth = $xml->getElementsByTagName('InfoType');
            $infoType = $array_auth->item(0)->nodeValue;
            $array_e = $xml->getElementsByTagName('ComponentVerifyTicket');
            $ticket = $array_e->item(0)->nodeValue;

    第二步 获取第三方平台component_access_token

       第三方平台compoment_access_token是第三方平台的下文中接口的调用凭据,也叫做令牌(component_access_token)。每个令牌是存在有效期(2小时)的,且令牌的调用不是无限制的,请第三方平台做好令牌的管理,在令牌快过期时(比如1小时           50分)再进行刷新。 令牌的维护可以参考微信的中控,我的处理方式是通过微信给我推送component_verify_ticket的10分钟间隔来做的。

         代码如下

           $weixinConfig = Config::get('weixin');
            $appId = $weixinConfig['app_id'];
            $appSecret = $weixinConfig['app_secret'];
    
            $postData = array(
                'component_appid' => $appId,
                'component_appsecret' => $appSecret,
                'component_verify_ticket' => $verifyTicket
            );
            $postData = json_encode( $postData );
            $result = $this->curl_post( 'https://api.weixin.qq.com/cgi-bin/component/api_component_token', $postData );

    第三步 获取预授权码pre_auth_code

      预授权码是每次要用的话通过access_token重新生成的,没有次数限制

      代码如下 

         $weixinConfig = Config::get('weixin');
            $appId = $weixinConfig['app_id'];
    
            $postData = array(
                'component_appid' => $appId
            );
            $postData = json_encode( $postData );
            $result = $this->curl_post( 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token='.$accessToken, $postData );

    第四步 进入微信授权页面

      进入微信授权页面会出现一个二维码,用户通过扫码在手机端进行授权操作,这里需要注意的一个东西是,进入微信授权页面时候需要传入一个回调地址,该回调地址后边可以跟参数,这样你本地代码和微信授权服务就一条线连起来了

      代码如下

         $weixinConfig = Config::get('weixin');
            $appId = $weixinConfig['app_id'];
            $hostMaps = Config::get('hostMaps');
            $wxAuthCallback = $hostMaps['wx_auth_callback'];
            $hostMaps = Config::get('hostMaps');
            $wxAuthRequest = $hostMaps['wx_auth_request'];
    
            $html_text = $this->buildRequestForm( array(), "POST", $wxAuthRequest.'?component_appid='.$appId.'&pre_auth_code='.$preAuthCode.'&redirect_uri='.$wxAuthCallback.'?callback_param='.$callbackParams, true );
    
        // 同步跳转方法(仿照支付宝)
         protected function buildRequestForm( array $param, $method, $target='',$jump=false) {
              $sHtml = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><form id='autoSubmit' action='".$target."' method='".$method."'>";
    
              if ( !empty( $param ) ) {
                  foreach( $param as $key => $value ) {
                      $sHtml.= "<input type='hidden' name='".$key."' value='".urldecode($value)."'/>";
                  }
              }
              $sHtml .= "</form>";
    
              if($jump) $sHtml = $sHtml."<script>document.getElementById("autoSubmit").submit();</script>";
    
              return $sHtml;
          }

    第五步 微信授权消息推送

      用户授权之后微信接收到授权结果,然后把授权结果推送给你授权时候的回调地址,推送消息里边会有一个 auth_code,你需要通过auth_code获取授权方的access_token(接口调用凭证);

      不同平台需求可能不一样,逻辑简单所以代码就不放了。

      有一点需要注意的是调用凭证access_token有两个小时的有效期,并且access_token获取是有次数限制的,所以需要做好本地维护工作,切入点是获取access_token的时间,每次从数据库中获取access_token时可以先判定一下获取时间然后再决定

      是直接用还是重新获取。

      判定代码如下

    strtotime("+ $verityAccessTime minutes", $createTime) < time()

     

    微信第三方授权流程网址 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=&lang=zh_CN

     

    本文为原创,创作不易,如要转载请注明本文出处;

     

    多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直

  • 相关阅读:
    Nginx常用日志分割方法
    nginx的 CPU参数worker_processes和worker_cpu_affinity使用说明
    js中的“==”和“===”的区别
    学习JS
    svg
    用户界面设计
    bootstrap和easyui
    axure—日期函数
    axure--轮播图
    字符串属性和函数的使用
  • 原文地址:https://www.cnblogs.com/hbyzs/p/6929895.html
Copyright © 2020-2023  润新知