news 2026/9/25 2:48:14

EasyWeChat 6.x 开放平台第三方平台实战示例:从推送事件接收、预授权到代公众号/小程序调用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EasyWeChat 6.x 开放平台第三方平台实战示例:从推送事件接收、预授权到代公众号/小程序调用
  • 后端
  • 即时通讯

【免费下载链接】easywechat

📦 一个 PHP 微信 SDK

项目地址:https://gitcode.com/gh_mirrors/ea/easywechat
点击查看免费下载

本篇基于 EasyWeChat 6.x(PHP 微信 SDK)的开放平台第三方平台模块,围绕其官方示例文档整理出一套可直接落地的实战方案:从 Laravel / Laravel Octane / webman 框架中接收开放平台推送消息、处理授权事件,到 6.3.0+ 新增的 PC 版预授权流程,以及基于 refresh_token / access_token 代公众号、代小程序调用 API,甚至代公众号响应回调消息。读完你可以直接在现有 PHP 框架中复刻整套第三方平台接入流程。

前置准备:实例化开放平台对象

示例中所有代码都基于一个已实例化的$app对象(即EasyWeChat\OpenPlatform\Application)。它需要开放平台账号的app_id、secret、token、aes_key四项核心配置,具体实例化方式可参考 开放平台模块总览。需要注意:不要把公众号/小程序的配置信息用来初始化开放平台对象。

在 Laravel / webman 等框架项目中,常见的做法是把配置放入config/wechatv6.php(如wechatv6.open_platform键),再通过new Application($config)创建实例:

use EasyWeChat\OpenPlatform\Application; $config = config('wechatv6.open_platform'); $app = new Application($config);

从源码结构看,Application是一个工厂类,所有模块(服务端、客户端、ComponentAccessToken、VerifyTicket、账户信息等)都从$app上按需访问(见 src/OpenPlatform/Application.php)。

一、Laravel:接收开放平台推送消息并处理授权事件

开放平台第三方平台的所有事件推送(授权成功、授权更新、授权取消、VerifyTicket)都会推送到你设置的「授权事件接收 URL」。假设该 URL 为https://easywechat.com/open-platform,在 Laravel 中只需在routes/web.php注册一个 POST 路由,把请求直接交给$app->server->serve():

// routes/web.php Route::post('open-platform', function () { // $app 为你实例化的开放平台对象,此处省略实例化步骤 return $app->server->serve(); // Done! });

⚠️ 注意:该路由需要排除 CSRF 校验(在 Laravel 的VerifyCsrfToken中间件白名单中排除该 URI)。

如果要处理具体事件,例如「授权成功」,可以注册handleAuthorized监听器,$message为微信推送的通知内容(EasyWeChat\OpenPlatform\Message实例),不同事件内容字段不同:

// 处理授权事件 Route::post('open-platform', function () { $server = $app->getServer(); // 处理授权成功事件,其他事件同理 $server->handleAuthorized(function ($message) { // $message 为微信推送的通知内容,不同事件不同内容,详看微信官方文档 // 获取授权公众号 AppId: $message['AuthorizerAppid'] // 获取 AuthCode:$message['AuthorizationCode'] // 然后进行业务处理,如存数据库等... }); return $server->serve(); });

这里有几个值得注意的源码细节(可印证 src/OpenPlatform/Server.php):

  • handleAuthorized()、handleUnauthorized()、handleAuthorizeUpdated()分别对应InfoType为authorized、unauthorized、updateauthorized三个事件,实现上通过中间件按InfoType分流(见 src/OpenPlatform/Server.php);
  • 官方示例中回调函数接收$message并直接使用$message['AuthorizerAppid']、$message['AuthorizationCode']取字段,Message类继承自EasyWeChat\Kernel\Message,支持数组式属性访问(见 src/OpenPlatform/Message.php);
  • serve()内部会先处理echostr服务端验证,再解密推送消息,并按中间件链处理事件,最终返回success或加工后的响应(见 src/OpenPlatform/Server.php)。

此外,component_verify_ticket事件已被 SDK 默认处理:getServer()每次被调用时会自动注入默认的 VerifyTicket 处理器,把推送中的ComponentVerifyTicket写入缓存(见 src/OpenPlatform/Application.php),因此即使你不注册任何监听器,直接serve()也能正常工作。

二、Laravel Octane(Swoole):长驻进程下的兼容写法

Laravel Octane(常配合 Swoole)下请求对象与常规 FPM 生命周期不同,需要把当前请求显式注入Application,再交给服务端处理:

// routes/web.php use EasyWeChat\OpenPlatform\Application; // 授权事件回调地址:http://easywechat.com/open-platform/server Route::post('open-platform/server', function () { $config = config('wechatv6.open_platform'); $app = new Application($config); // 兼容octane $app->setRequestFromSymfonyRequest(request()); $server = $app->getServer(); return $server->serve(); });

关键点在于setRequestFromSymfonyRequest(request()):Application内部通过InteractWithServerRequestTrait 持有 PSR-7 风格的请求对象(见 src/OpenPlatform/Application.php),getServer()构造的Server会从该请求中读取echostr、signature、timestamp、nonce、msg_signature等查询参数以及推送的 XML 消息体,因此在 Swoole/Octane 这类「请求对象需手动绑定」的场景下,显式注入当前请求是保证消息验签与解密正确的必要步骤。

三、webman:手动构造 Symfony Request 接收推送

webman 同样需要把原生请求转换为Symfony\Component\HttpFoundation\Request后注入Application。示例中通过手动组装参数、Cookie、原始 Body 与 Header 实现:

namespace app\controller; use EasyWeChat\OpenPlatform\Application; use support\Request; use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; // 授权事件回调地址:http://easywechat.com/openPlatform/server class OpenPlatform { public function server(Request $request) { $config = config('wechatv6.open_platform'); $app = new Application($config); $symfony_request = new SymfonyRequest($request->get(), $request->post(), [], $request->cookie(), [], [], $request->rawBody()); $symfony_request->headers = new HeaderBag($request->header()); $app->setRequestFromSymfonyRequest($symfony_request); $server = $app->getServer(); $response = $server->serve(); return $response->getBody()->getContents(); } }

这段代码把 webman 的support\Request中的 GET、POST、Cookie、原始请求体(rawBody(),推送的 XML 就在这里)以及请求头完整搬运到 Symfony Request 上,再通过setRequestFromSymfonyRequest()注入。返回时取$response->getBody()->getContents(),以适配 webman 的响应格式。验签所需的signature等参数来自查询字符串,头部则用于框架层面兼容,二者缺一不可。

四、开放平台 PC 版预授权流程(6.3.0+)

从 6.3.0 版本开始,SDK 提供了createPreAuthorizationUrl()与createPreAuthorizationCode(),可以一键生成预授权码并拼装授权页地址(旧版本需要手动调微信接口拿预授权码,再自行拼 URL)。

一个完整的 Laravel 预授权用例包含「授权落地页」与「授权跳转页」两个路由:

// routes/web.php // 授权落地页 Route::any('open-platform/auth', function(){ $auth_code = request()->get('auth_code'); // 完成授权写入数据库的逻辑省略。。。 })->name('open_platform.auth'); // 授权跳转页 Route::any('open-platform/preauth', function(){ // $app 为你实例化的开放平台对象,此处省略实例化步骤 $options=[ //1 表示手机端仅展示公众号;2 表示仅展示小程序,3 表示公众号和小程序都展示。如果为未指定,则默认小程序和公众号都展示。 // 'auth_type' => '', // 指定的权限集id列表,如果不指定,则默认拉取当前第三方账号已经全网发布的权限集列表。 // 'category_id_list' => '', ]; $url = $app->createPreAuthorizationUrl(route('open_platform.auth'), $options); return response("<script>window.location.href='$url';</script>")->header('Content-Type', 'text/html'); });

参数说明:

参数说明
auth_type展示类型:1手机端仅展示公众号;2仅展示小程序;3公众号和小程序都展示。不传则默认小程序和公众号都展示
category_id_list指定的权限集 id 列表;不指定则默认拉取当前第三方账号已全网发布的权限集列表

从源码看,createPreAuthorizationUrl(string $callbackUrl, array|string $optional = [])的实现逻辑是(见 src/OpenPlatform/Application.php):

  • 若$optional是字符串,则兼容旧版 API,把它当作pre_auth_code使用;
  • 若传入数组,则自动调用createPreAuthorizationCode()获取pre_auth_code填充;
  • 最终把pre_auth_code、component_appid、redirect_uri等参数拼装到https://mp.weixin.qq.com/cgi-bin/componentloginpage?...上。

所以上面的示例即使不显式传pre_auth_code,方法内部也会自动完成「创建预授权码 → 拼授权页地址」的全过程。授权完成后,微信会携带auth_code与expires_in跳回落地页(如https://easywechat.com/callback?auth_code=xxx&expires_in=600),你可以用$app->getAuthorization($auth_code)换取授权方信息(见 获取授权信息)。

五、代公众号 / 代小程序调用 API(6.3.0+)

第三方平台最常见的业务是代替已授权的公众号、小程序调用其接口。6.3.0+ 提供了两条便捷入口:

  • getOfficialAccountWithRefreshToken($appId, $refreshToken):传入公众号appid与授权时拿到的authorizer_refresh_token,返回EasyWeChat\OfficialAccount\Application实例;
  • getMiniAppWithRefreshToken($appId, $refreshToken):同上,返回EasyWeChat\MiniApp\Application实例。

这两个方法内部都会先调用getAuthorizerAccessToken(),其实现会对 token 做按 appid + refresh_token 维度缓存,缓存键为open-platform.authorizer_access_token.{appid}.{md5(refresh_token)},并以expires_in - 500秒的余量写入缓存,未命中时才回源refreshAuthorizerToken()刷新(见 src/OpenPlatform/Application.php),因此高并发场景下不必担心频繁触发刷新接口的每日限额。

一个同时演示「代小程序」和「代公众号」的 Laravel 控制器示例如下。首先配置路由:

// routes/web.php // 例如:https://easywechat.com/open-platform/miniapp/get-phone-number/wx123212312313abc Route::any('open-platform/miniapp/get-phone-number/{appid}', 'OpenPlatformController@getPhoneNumber'); Route::any('open-platform/officialAccount/get-user-list/{appid}', 'OpenPlatformController@getUsers');

对应控制器app/Http/Controllers/OpenPlatformController:

use App\Http\Controllers\Controller; class OpenPlatformController extends Controller { public function mini(string $appid): \EasyWeChat\MiniApp\Application { $refreshToken = '授权后在缓存或数据库获取'; // $app 为你实例化的开放平台对象,此处省略实例化步骤 return $app->getMiniAppWithRefreshToken($appid, $refreshToken); } public function officialAccount(string $appid): \EasyWeChat\OfficialAccount\Application { $refreshToken = '授权后在缓存或数据库获取'; // $app 为你实例化的开放平台对象,此处省略实例化步骤 return $app->getOfficialAccountWithRefreshToken($appid, $refreshToken); } public function getUsers(string $appid) { return $this->officialAccount($appid) ->getClient() ->get('cgi-bin/users/list') ->toArray(); } public function getPhoneNumber(string $appid) { $data = [ 'code' => (string) request()->get('code'), ]; return $this->mini($appid) ->getClient() ->postJson('wxa/business/getuserphonenumber', $data) ->toArray(); } }

核心要点:

  • 返回的Application实例可直接用->getClient()调用该公众号/小程序任意 API,SDK 会自动携带代调用所需的authorizer_access_token;
  • 代调用的小程序、公众号对象实际是EasyWeChat\MiniApp\Application与EasyWeChat\OfficialAccount\Application,其 Client 的 token 来自AuthorizerAccessToken(见 src/OpenPlatform/AuthorizerAccessToken.php),并通过setAccessToken()注入(见 src/OpenPlatform/Application.php);
  • authorizer_access_token有效期仅 2 小时,SDK 内部通过缓存 + 自动刷新机制管理,你只需持久化authorizer_refresh_token即可。

除了 refresh_token 方式,6.3.0+ 还支持直接使用authorizer_access_token的getOfficialAccountWithAccessToken()/getMiniAppWithAccessToken(),适用于「独立中央授权服务单独维护授权信息」的架构;旧版通过new AuthorizerAccessToken($appId, $token)+getOfficialAccount()/getMiniApp()的方式官方示例中已标注不推荐使用。更多细节见 开放平台模块总览。

六、代公众号处理回调事件

第三方平台还可以代替公众号接收并响应用户发来的消息。示例中在同一个回调路由里,根据 URL 中的{appid}取出对应授权方的 refresh_token,构造公众号对象并注册消息监听器:

// 代公众号处理回调事件 Route::any('callback/{appid}', function ($appId) { // $app 为你实例化的开放平台对象,此处省略实例化步骤 // $refreshToken 为授权后你缓存或数据库中的 authorizer_refresh_token,此处省略获取步骤 $refreshToken = '你已缓存或数据库中的 authorizer_refresh_token'; $server = $app->getOfficialAccountWithRefreshToken($appId, $refreshToken)->getServer(); $server->addMessageListener('text', function ($message) { return sprintf("你对 overtrue 说:“%s”", $message->Content); }); return $server->serve(); });

这里getOfficialAccountWithRefreshToken()返回的公众号对象自带getServer()服务端,其加密参数(token、aes_key、Encryptor)会复用开放平台的配置(见 src/OpenPlatform/Application.php),因此代公众号回调同样走「验签 → 解密 → 消息监听器 → 加密回复」的完整链路。addMessageListener('text', ...)注册的是文本消息处理器,$message->Content即用户发送的文本内容,返回字符串即自动回复。更多服务端用法(handleAuthorized/handleUnauthorized/handleAuthorizeUpdated/ 自定义中间件 /getDecryptedMessage等)可参考 服务端使用文档。

七、周边模块衔接与注意事项

  • CSRF 排除:开放平台事件推送与回调路由必须从 Laravel CSRF 白名单中排除,否则会收到 419 响应;
  • VerifyTicket 默认处理:component_verify_ticket事件由 SDK 默认写入缓存(缓存键open_platform.verify_ticket.{app_id},见 src/OpenPlatform/VerifyTicket.php),ComponentAccessToken的获取与刷新都依赖它(见 src/OpenPlatform/ComponentAccessToken.php)。若你自行接管 VerifyTicket 推送,必须同时注入自定义ComponentAccessToken,否则会因缺少 ticket 而无法换取component_access_token;
  • token 缓存策略:ComponentAccessToken以expires_in - 100秒写入缓存,authorizer_access_token以expires_in - 500秒写入缓存,均预留了时钟偏差余量,请勿再手动缩短或重复刷新;
  • 代调用入口:公众号代调用详见 公众号模块,小程序代调用详见 小程序模块,普通 API 调用方式见 API Client 文档;
  • 网页授权:第三方应用/网站的网页授权通过$app->getOAuth()获取,逻辑与公众号网页授权基本一致,详见 网页授权;
  • 授权码换授权信息:$app->getAuthorization($authCode)返回的Authorization对象可依次取得getAppId()、getAccessToken()(AuthorizerAccessToken实例)、getRefreshToken(),并支持toArray()/toJson()序列化,便于落库(对应实现见 src/OpenPlatform/Authorization.php)。

附:如何验证与继续深入

仓库中 tests/OpenPlatform/ApplicationTest.php 提供了上述能力的单元测试佐证:test_get_authorization验证了换取授权信息时 POST 到cgi-bin/component/api_query_auth且请求体包含component_appid与authorization_code;test_refresh_authorizer_token验证了刷新令牌接口cgi-bin/component/api_authorizer_token的请求参数拼装;test_get_official_account/test_get_mini_app验证了代调用返回的实例类型。接入时若遇到验签失败、消息解密异常或 token 类问题,可对照这些测试与上述源码路径定位。想要继续完善本文示例,欢迎按 贡献指南 向 EasyWeChat 文档仓库补充更多框架的接入用例。

  • 后端
  • 即时通讯

【免费下载链接】easywechat

📦 一个 PHP 微信 SDK

项目地址:https://gitcode.com/gh_mirrors/ea/easywechat
点击查看免费下载

相关推荐

上一篇:球谐函数算子深度解析:gauss-splat如何用Ascend C计算视角相关颜色(Fwd/Bwd实现走读)
下一篇:彻底解决分布式并发!yudao-cloud基于Redisson实现跨服务锁机制

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 2:46:44

4路CAN FD免驱工具:LTE远程调试+故障注入全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 2:44:26

猫抓浏览器扩展最短路径实操:网页媒体嗅探与 M3U8 离线保存

猫抓浏览器扩展最短路径实操&#xff1a;网页媒体嗅探与 M3U8 离线保存 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓&#xff08;cat-catch…

作者头像 李华
网站建设 2026/9/25 2:43:51

旧安卓手机变身Klipper监控摄像头:IP Webcam接入配置与排坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华