微信第三方平台授权

时间:2024-03-01 18:44:19

本文是微信第三方平台授权

1.    写在前面

(1)环境:php5.6+easyWechat3.1

(2)easyWechat目前最新版本是4.0,但是需要php7以上的运行环境。如果是php5.6环境还是只能用3.1版本。有条件的尽量可以使用最新版本,因为新版本文档更详细,支持的功能更全面;

(3)具体的接口调用和授权过程以微信开放平台文档(微信开放平台->资源中心->第三方平台,注意不是微信开发者文档)和easyWechat官方文档为主,可以先阅读一下这两个文档,了解一下授权过程;

(4)同时各主流框架都已经支持该插件,详见easyWechat文档;这个demo使用原生的php+easyWechat;

2.    授权需要的准备

(1)    微信第三方平台申请以及后台配置;申请:微信第三方平台的相关审核资料填写授权发起地址的域名、授权事件接收URL、服务器的ip白名单;这些都非常重要,后面开发会用到;而且微信审核都会需要一定时间;

(2)    域名和服务器,微信授权发起地址和通知地址是需要域名,具体请参考微信第三方平台申请需求;

授权过程

(1)    下载easyWechat,参考easyWechat官方文档,使用composer下载;

(2)    配置文件config.php;

$options      = [
    \'open_platform\' => [
        \'app_id\'  => \'wx*******\',
        \'secret\'  => \'*******\',
        \'token\'   => \'QPh4Dj*****9\',
        \'aes_key\' => \'sdfsof*****dflsdd\'
    ],

    /**
     * OAuth 配置
     *
     * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
     * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
     */
    \'oauth\' => [
        \'scopes\' => [\'snsapi_userinfo\'],
        \'callback\' => \'/callback\', //授权回调地址
    ],
];

$appurl = "http://******t/";

 

这里面有第三方平台的相关信息配置,这些都在微信开发者平台中能取到;

(3)    授权入口文件index.php;

<?php
/**
 * 第三方授权
 * User: Julian
 * Date: 2018/6/7
 */
include __DIR__ . \'/vendor/autoload.php\'; // 引入 composer 入口文件

use EasyWeChat\Foundation\Application;

include __DIR__ . \'/config.php\'; // 引入 配置 入口文件

/**
 * 使用easywechat获取授权跳转地址
 */
$app          = new Application($options);
$openPlatform = $app->open_platform;
$callback     = $appurl.\'callbackFromPlatform.php\'; //授权成功回调地址
$response     = $openPlatform->pre_auth->redirect($callback);
//授权跳转地址
$url          = $response->getTargetUrl();
//注意 这里不能重定向直接跳转,会报发起域名为空的错 放到页面上点击或者跳转
echo "<a href=\'$url\'>点击授权</a>";

    此页面只做了一个授权点击调转,如果会有一个waring:关于时区问题的话可以不管。也可以按照easyWechat官方文档的常见问题处理;

    注意根据微信的官方文档授权过程还包括预授权码等一系列繁琐的验证,这里不用担心,easyWechat都已经做好了,有兴趣可以看一下他的源码

(4)点击跳转,就会调转到微信的一个授权页,需要公众号的管理员扫码授权;授权结果会通过微信后台配置的授权;事件接收URL异步通知;Demo里面配置的是到message.php;

message.php中参考文档做了一个自定义处理,其实就是在授权结果的返回时写了一个日志;也可以直接返回;这里还包括微信服务器10分钟一次的通知component_verify_ticket

<?php
/**
 * 授权事件接收地址
 * User: Julian
 * Date: 2018/6/7
 */

include __DIR__ . \'/vendor/autoload.php\'; // 引入 composer 入口文件

use EasyWeChat\Foundation\Application;

include __DIR__ . \'/config.php\'; // 引入 配置 入口文件

$app = new Application($options);
$openPlatform = $app->open_platform;
// 默认处理方式
$openPlatform->server->serve();

// 自定义处理,这里只写了一个日志;授权的信息easychart自动做了缓存

$openPlatform->server->setMessageHandler(function($event ) use ($openPlatform){
    // 事件类型常量定义在 \EasyWeChat\OpenPlatform\Guard 类里
    $myfile = fopen("log.txt", "a");

    switch ($event->InfoType) {
        case \'authorized\':
            $authorizationInfo = $openPlatform->getAuthorizationInfo($event->AuthorizationCode)->authorization_info;
            $txt = "授权成功!appid:" . $authorizationInfo["authorizer_appid"] . \'  token\'.$authorizationInfo["authorizer_access_token"];
            fwrite($myfile, $txt."\n");
            break;
        case \'unauthorized\':
            $txt = "授权取消!\n";
            fwrite($myfile, $txt);
            break;
        case \'updateauthorized\':
            $authorizationInfo = $openPlatform->getAuthorizationInfo($event->AuthorizationCode)->authorization_info;
            $txt = "更新授权!appid:" . $authorizationInfo["authorizer_appid"] . \'  token\'.$authorizationInfo["authorizer_access_token"];
            fwrite($myfile, $txt."\n");
            break;
        case \'component_verify_ticket\':
            //十分钟通知一次的component_verify_ticket
            $txt = "component_verify_ticket!\n";
            fwrite($myfile, $txt);
            break;
        default:
            $txt = "default!\n";
            fwrite($myfile, $txt);
            break;
    }
    fclose($myfile);
});

//如果不用自定义处理的话可以直接返回
$openPlatform->server->serve();

关于授权结果的返回带的authorizer_appid、authorizer_access_token、authorizer_refresh_token以及component_verify_ticket,easyWechat会自己缓存起来,然后在调用的时候取出,同时根据文档也支持redis等缓存,没有配置的话就默认文件缓存;

(5)授权完成之后会跳转到授权之前配置的回调地址,demo里面配置的是callbackFromPlatform.php,具体逻辑见代码注释;这里要注意的是:

  授权的微信公众号微信后台的开发者模式 “启用”;

  授权的微信公众号相关接口一定要调用权限这个在授权者的公众号后台都可以看到;

以上两点保证了授权之后才能正常调用相关的接口;

<?php
/**
 * 授权给第三方平台之后的回调
 * User: Julian
 * Date: 2018/6/7
 */

include __DIR__ . \'/vendor/autoload.php\'; // 引入 composer 入口文件
include __DIR__ . \'/config.php\'; // 引入 配置 入口文件

use EasyWeChat\Foundation\Application;


$app          = new Application($options);
$openPlatform = $app->open_platform;




//授权返会的授权信息
//$authorizationInfo[\'authorizer_appid\']  授权的公众号的appid
//$authorizationInfo["authorizer_access_token"] 授权的公众号的access_token 有效时间是2小时
//$authorizationInfo["authorizer_refresh_token"] 授权的公众号的refresh_token 用作失效时候的刷新
$authorizationInfo = $openPlatform->getAuthorizationInfo()->authorization_info;

var_dump($authorizationInfo);
//代替授权的公众号调用接口 必须保证该公众号后台已经有该接口的调用权限 否则会报api unauthorized hint
//获取微信ip 直接用accesstoken调用接口
$url = \'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=\'.$authorizationInfo["authorizer_access_token"];
var_dump(curlGet($url));

$wechat = $app->open_platform->createAuthorizerApplication($authorizationInfo[\'authorizer_appid\'], $authorizationInfo["authorizer_refresh_token"]);

//用封装的方法调用接口
$userService = $wechat->user;
$userList = $userService->lists($nextOpenId = null);
var_dump($userList);die;


function curlGet($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);

    $res = curl_exec($ch);

    curl_close($ch);
    if($res) {
        return $res;
    } else {
        return json_encode([
            "code"    => 400,
            "message" => "接口返回异常"
        ]);
    }
}

 

6.授权之后掉demo里面写了两种调用方式,一种是easyWechat中封装好的,一种是直接根据微信文档调用;我们发现调用接口其实只需要一个参数,也就是授权之后的返回的authorizer_access_token,需要注意的是authorizer_access_token的有限期只有两个小时,而且每天都会有额定刷新次数,这里建议自己做个缓存,authorizer_access_token到期之后用authorizer_refresh_token刷新;具体操作见微信开放平台的api第五条(https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=&lang=zh_CN);