一、准备微信开发平台账号(需要认证¥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、异常:请确认授权入口页所在域名,与授权后回调页所在域名相同,并且,此两者都必须与申请第三方平台时填写的授权发起页域名相同。授权入口页所在域名:空
第一种方式:
第二种方式: 重定向
8、有可能会出现你每次启动项目的时候,由于每10分钟才会验证一次Ticket,那么直接调用接口,如果服务器还没推送,会出现ticket失效(不过在正式环境还好)(就算全网通过后也会推送component_verify_ticket协议)。
9、每次授权后,想要获取最新的权限必须重新扫码授权。否则无法获取最新的消息。
10、获取令牌的官网接口
11、第三方中的授权的URL一级接收公众号消息的URL都只能在同一个一级域名下