EasyWeChat微信开发平台第三方接入(Laravel5+,EasyWeChat3.0/EasyWeChat4.0)

一、准备微信开发平台账号(需要认证¥300)

二、看代码(注意:其中有自己建的数据表)

1、EasyWeChat 3.0 微信开发平台第三方平台接入

 [
            'app_id'   => 'xx',
            'secret'   => 'xx',
            'token'    => 'xxx',
            'aes_key'  => 'xxx'
        ],
    ];

    public function index(Request $request) {

        $this->request = $request;

        try{
            $app = new Application($this->options);
            $openPlatform = $app->open_platform; 
            
            // 自定义处理
            $server = $openPlatform->server;
            $server->setMessageHandler(function($event) use($openPlatform){
                switch ($event->InfoType) {
                    //授权成功
                    case 'authorized':                
                        $res = $openPlatform->getAuthorizationInfo($event->AuthorizationCode);
                        $appid2 = $res->authorization_info['authorizer_appid'];
                        $refresh_token = $res->authorization_info['authorizer_refresh_token'];

                        $data = $openPlatform->getAuthorizerInfo($appid2);

                        $account = Account::where('appid', $appid2)->first();
                        $info2 = $data['authorizer_info'];
                        $info1 = $data['authorization_info'];
                        if(is_null($account)){
                            $account = Account::create([
                                'appid' => $info1['authorizer_appid'],
                                'refresh_token' => $refresh_token,
                                'name' => $info2['nick_name'],
                                'head_img' => $info2['head_img'],
                                'original' => $info2['user_name'],
                                'com_main_body' => $info2['principal_name'],
                                'headimg' => $info2['qrcode_url'], //二维码
                                'status' => 1,
                                'level' => $this->getLevel($info2),
                                'type' => 0, 
                                'token' => random(32),
                                'encodingaeskey' => random(43)
                            ]);
                        }else{
                            $account->refresh_token = $refresh_token;
                            $account->name =  $info2['nick_name'];
                            $account->type = 0;
                            $account->original = $info2['user_name'];
                            $account->level = $this->getLevel($info2);
                            $account->head_img = $info2['head_img'];
                            $account->save();
                        }
                        break;
                    //取消授权
                    case 'unauthorized':
                        $appid = $event->AuthorizerAppid;
                        $account = Account::where('appid', $appid)->first();
                        if(!is_null($account)){
                            $account->refresh_token = '';
                            $account->save();
                        }
                    //推送component_verify_ticket协议
                    case 'component_verify_ticket':
                        $appid = $event->AppId;         
                        $ticket = $event->ComponentVerifyTicket;
                    
                    	Redis::set($appid . '_component_verify_ticket',$ticket);//存储起来方便后续多台服务器并发调用
                    
                        $wechatTicket = WechatTicket::where('appid', $appid)->orderBy('id')->first();
                        if(is_null($wechatTicket)){
                            $wechatTicket = WechatTicket::create([
                                'appid' => $appid,
                                'ticket' => $ticket,
                                'create_time' => time(),
                                'update_time' => time()
                            ]);
                        }else{
                           $wechatTicket->ticket = $ticket;
                           $wechatTicket->update_time = time();
                           $wechatTicket->save();
                        }
                }
            });              
            return $server->serve();
 
        }catch(\Exception $e){
            if(env('APP_DEBUG')){
                echo $e->getMessage();
            } else {
                 abort(404);
            }
        }


    }


    public function auth(Request $request) {
        $app = new Application($this->options);
        $openPlatform = $app->open_platform;

        $response = $openPlatform->pre_auth->redirect('http://xxx//index');
        
        //return $response;
        // 获取跳转的链接
        $url = $response->getTargetUrl();
        echo '点击第三方授权';
    }


}

 

2、EasyWeChat 4.0微信开发平台第三方平台接入

request = $request;
        try{
            $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));

            // 第三方平台接入处理
            $server = $openPlatform->server;
            // 处理授权成功事件
            $server->push(function ($event) use($openPlatform){
                //获取(刷新)授权公众号或小程序的接口调用凭据(令牌)              
                $res = $openPlatform->handleAuthorize($event->AuthorizationCode);
                $appid2 = $res->authorization_info['authorizer_appid'];
                $refresh_token = $res->authorization_info['authorizer_refresh_token'];

                //获取授权方的帐号基本信息
                $data = $openPlatform->getAuthorizer($appid2);
                $account = Account::where('appid', $appid2)->first();
                $info2 = $data['authorizer_info'];
                $info1 = $data['authorization_info'];
                if(is_null($account)){
                    $account = Account::create([
                        'appid' => $info1['authorizer_appid'],
                        'refresh_token' => $refresh_token,
                        'name' => $info2['nick_name'],
                        'head_img' => $info2['head_img'],
                        'original' => $info2['user_name'],
                        'com_main_body' => $info2['principal_name'],
                        'headimg' => $info2['qrcode_url'], //二维码
                        'status' => 1,
                        'level' => $this->getLevel($info2),
                        'type' => 0, 
                        'token' => random(32),
                        'encodingaeskey' => random(43)
                    ]);
                }else{
                    $account->refresh_token = $refresh_token;
                    $account->name =  $info2['nick_name'];
                    $account->type = 0;
                    $account->original = $info2['user_name'];
                    $account->level = $this->getLevel($info2);
                    $account->head_img = $info2['head_img'];
                    $account->save();
                }
            }, Guard::EVENT_AUTHORIZED);


            // 处理授权更新事件
            $server->push(function ($event) use($openPlatform){
                
            }, Guard::EVENT_UPDATE_AUTHORIZED);

            // 处理授权取消事件
            $server->push(function ($event) {
                $appid = $event->AuthorizerAppid;
                $account = Account::where('appid', $appid)->first();
                if(!is_null($account)){
                    $account->refresh_token = '';
                    $account->save();
                }
            }, Guard::EVENT_UNAUTHORIZED);

            //VerifyTicket component_verify_ticket协议推送
            $server->push(function ($event) use($openPlatform){
                $appid = $event->AppId;         
                $ticket = $event->ComponentVerifyTicket;
                
                //保存component_verify_ticket协议
                Redis::set($appid . '_component_verify_ticket', $ticket);//存储起来方便后续多台服务器并发调用
            
                $wechatTicket = WechatTicket::where('appid', $appid)->orderBy('id')->first();
                if(is_null($wechatTicket)){
                    $wechatTicket = WechatTicket::create([
                        'appid' => $appid,
                        'ticket' => $ticket,
                        'create_time' => time(),
                        'update_time' => time()
                    ]);
                }else{
                    $wechatTicket->ticket = $ticket;
                    $wechatTicket->update_time = time();
                    $wechatTicket->save();
                }
            }, Guard::EVENT_COMPONENT_VERIFY_TICKET);
             
            return $server->serve();
            
        }catch(\Exception $e){
            if(env('APP_DEBUG')){
                echo $e->getMessage();
            } else {
                 abort(404);
            }
        }

    }

    public function auth(Request $request) {
        try{      
            $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));
            // 获取跳转的链接
            $url = $openPlatform->getPreAuthorizationUrl('url');
            // 获取跳转的链接
            echo '点击第三方授权';
        }catch(\Exception $e){
            //echo $e->getMessage();
            $url = '';
        }
        //return view('admin.auth.note', compact('url'));
    }

    public function callback(Request $request) {
        $filter =  $request->all();
        //return redirect()->to(site_path('account/wechat', 'admin'))->with('message', '第三方接入成功!');
        return redirect()->to('url')->with('message', '第三方接入成功!');
    }

    // 公众号分组
    public function getLevel($info = array()){
        $level = 0;
        if(!empty($info['MiniProgramInfo'])){
            $level = 5;
        }else if($info['service_type_info']['id'] == 0 || $info['service_type_info']['id'] == 1){
            //订阅号
            if($info['verify_type_info']['id'] >= 0){
                //已认证
                $level = 3;
            }else{
                $level = 1;
            }
        }else if($info['service_type_info']['id'] == 2){
            //服务号
            if($info['verify_type_info']['id'] >= 0){
                //已认证
                $level = 4;
            }else{
                $level = 2;
            }
        }
        return $level;
    }


}

调用auth函数进行第三方授权

3、自定义推送component_verify_ticket协议

    EasyWeChat自动缓存了component_verify_ticket。

    想在不同的服务器将进行操作,必须将component_verify_ticket保存到数据库(Redis,Mysql)。

    看下面的代码:EasyWeChat4.0

            $openPlatform = Factory::openPlatform(config('wechat.open_platform.default'));  
            $verify_ticket = $openPlatform->verify_ticket;
            //重设第三方平台verify_ticket 方便多台机器用
            $app_id = $openPlatform->config->app_id;
            
            //Redis
            $ticketCache = Redis::get($app_id . '_component_verify_ticket');
            
            if(is_null($ticketCache) || empty($ticketCache)){
                //mysql
                $wechatTicket = WechatTicket::where('appid', $app_id)->orderBy('id')->first();
                if(!is_null($wechatTicket)){
                    $ticketCache = $wechatTicket->ticket;
                }
            }
            
            if($ticketCache){
                $verify_ticket->setTicket($ticketCache);
            } 
            
            //代公众号实现业务
            $app = $openPlatform->officialAccount($account->appid, $account->refresh_token);

            //代小程序实现业务
            //$app = $openPlatform->miniProgram($account->appid, $account->refresh_token);

三、问题

1、在授权URL测试的时候,如果报AesException: 签名验证错误,可能是代码你参数填写有错。一定要注意是填写第三方平台的信息,不是公众号的信息。

2、在授权URL测试的时候,如果报Illegal key size,那么就是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件。去掉这种限制需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(https://yunpan.cn/cSrtk3Fk6WgAs  访问密码 244a)。替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar(jdk,jre最好都替换。)。注意一定要重启TOMCAT才能生效。

3、component ticket is exprie ticket过期,每10分钟会微信服务器会推送到授权事件的URL中。这里可以不用处理设置过期时间(因为这里的ticket是无接口调用权限的,而且是微信服务器自己推送的)

4、注意公众号消息处理的URL必须加上$APPID$

5、component_access_token过期时间为2个小时,和公众号的Token一样(我处理的是存储过期时间,超过就请求。而不是定时刷新)

6、可以选择你自己需要第三方托管的权限集,比如你其他消息只走微信公众号,只有客服消息走第三方平台。

7、异常:请确认授权入口页所在域名,与授权后回调页所在域名相同,并且,此两者都必须与申请第三方平台时填写的授权发起页域名相同。授权入口页所在域名:空

EasyWeChat微信开发平台第三方接入(Laravel5+,EasyWeChat3.0/EasyWeChat4.0)_第1张图片

 

(改地址不能直接方法,需要标签进行跳转)

   当配置正常,不能正常访问时,可以试试以下

   第一种方式:

   第二种方式: 重定向

8、有可能会出现你每次启动项目的时候,由于每10分钟才会验证一次Ticket,那么直接调用接口,如果服务器还没推送,会出现ticket失效(不过在正式环境还好)(就算全网通过后也会推送component_verify_ticket协议)。

9、每次授权后,想要获取最新的权限必须重新扫码授权。否则无法获取最新的消息。

10、获取令牌的官网接口

EasyWeChat微信开发平台第三方接入(Laravel5+,EasyWeChat3.0/EasyWeChat4.0)_第2张图片

11、第三方中的授权的URL一级接收公众号消息的URL都只能在同一个一级域名下

12、如果是并发量大,做集群的话,一定要把所有服务器的ip都加到白名单中

你可能感兴趣的:(php)