后端即时通讯【免费下载链接】easywechat 一个 PHP 微信 SDK项目地址https://gitcode.com/gh_mirrors/ea/easywechat点击查看免费下载本篇技术指南以 EasyWeChat 3.x 官方文档《网页授权》docs/src/3.x/oauth.md为骨架系统讲解微信公众平台网页授权OAuth2.0的协议原理、授权流程、公众号后台域名配置以及 EasyWeChat 中oauth模块的发起授权、获取用户信息两大核心 API 与完整落地实例并结合当前仓库源码如 src/OfficialAccount/Application.php解析其底层实现。阅读完本文你将能够独立完成一个微信内网页登录并获取用户资料的完整功能。关于 OAuth2.0OAuth 是一个关于授权authorization的开放网络标准在全世界得到广泛应用目前的版本是 2.0 版对应国际标准 RFC 6749。它解决的核心问题是客户端应用如何在不接触用户密码的情况下安全地获得访问用户受保护资源的权限。下图展示了 OAuth 协议的标准角色与交互时序-------- --------------- | |--(A)- Authorization Request -| Resource | | | | Owner | | |-(B)-- Authorization Grant ---| | | | --------------- | | | | --------------- | |--(C)-- Authorization Grant --| Authorization | | Client | | Server | | |-(D)----- Access Token -------| | | | --------------- | | | | --------------- | |--(E)----- Access Token ------| Resource | | | | Server | | |-(F)--- Protected Resource ---| | -------- --------------- OAuth 授权流程该图摘自 RFC 6749六步含义如下A用户打开客户端以后客户端要求用户给予授权。B用户同意给予客户端授权。C客户端使用上一步获得的授权向认证服务器申请令牌。D认证服务器对客户端进行认证以后确认无误同意发放令牌。E客户端使用令牌向资源服务器申请获取资源。F资源服务器确认令牌无误同意向客户端开放资源。微信网页授权正是这套标准流程在微信生态内的落地实现只是把其中的认证服务器 / 资源服务器替换成了微信服务器令牌替换成了网页授权access_token与openid。微信的两种 OAuth在微信里OAuth 其实有两种形态公众平台网页授权获取用户信息与开放平台网页登录。它们的区别主要有两处授权地址不同、scope不同。维度公众平台网页授权开放平台网页登录适用场景公众号内网页微信内浏览器访问网站 Web 端扫码登录授权 URLhttps://open.weixin.qq.com/connect/oauth2/authorizehttps://open.weixin.qq.com/connect/qrconnectScopessnsapi_base与snsapi_userinfosnsapi_login其中snsapi_base为静默授权用户无感知仅能拿到openidsnsapi_userinfo会弹出蓝色授权确认页可进一步获取昵称、头像等用户资料。网页授权的完整流程无论哪种授权形态其逻辑都是一致的。以业务页面/user/profile为例完整流程如下用户尝试访问业务页面例如/user/profile如果用户已经登录则正常显示该页面系统检查当前访问的用户并未登录从 session 或者其它方式检查则跳转到微信授权服务器上面两种中的一种授权 URL并告知微信授权服务器我们的回调 URLredirect_uricallback.php此时用户会看到蓝色的授权确认页面scope为snsapi_base时不显示用户点击确定完成授权浏览器跳转到回调 URLcallback.php并带上code?codeCODEstateSTATE在callback.php中得到code后通过code再次向微信服务器请求得到网页授权 access_token与openid可以选择拿openid去请求 API 得到用户信息可选将用户信息写入 SESSION跳转到第 3 步写入的target_url页面/user/profile。使用 SDK 时以上繁杂的协议细节都会被封装起来开发者无需关心。注意第 3 步redirect_uricallback.php实际上我们会在callback.php后面还带上授权目标页面user/profile所以完整的redirect_uri应该用 PHP 拼接出来redirect_uri.urlencode(callback.php?targetuser/profile)最终结果为redirect_uricallback.php%3Ftarget%3Duser%2Fprofile。也就是说授权完成后微信会带着code跳回callback.php而我们通过额外参数记录授权前的目标页面以便授权完成后原路返回。逻辑组成三个页面从上述流程可以看出一个完整的网页授权登录功能至少由 3 个页面组成业务页面需要授权才能访问的页面如/user/profile发起授权页此页面其实可以省略可以做成一个中间件全局检查未登录就发起授权授权回调页接收用户授权后的状态并获取用户信息写入用户会话状态SESSION。在框架化开发中发起授权页通常被抽象为路由中间件如 Laravel 的 middleware实现全局未登录即跳授权的效果与 EasyWeChat 官方文档中的描述一致。开始之前配置网页授权域名在动手写代码之前请务必先在公众号后台完成域名配置否则授权会直接失败登录公众号后台找到边栏开发模块下的接口权限点击网页授权获取用户基本信息后面的修改添加你的网页授权域名。注意如果你的授权地址为http://www.abc.com/xxxxx那么请填写www.abc.com。也就是说必须填写与网址完全匹配的域名——如果填写abc.com是通不过校验的。配置 OAuth 参数在 EasyWeChat 3.x 中OAuth 相关配置放在初始化Application的oauth配置项下。完整参考见 docs/src/3.x/configuration.md核心配置如下use EasyWeChat\Foundation\Application; $options [ app_id your-app-id, // AppID secret your-app-secret, // AppSecret token your-token, // Token明文/兼容/安全模式 aes_key , // EncodingAESKey安全模式与兼容模式下请务必填写 // ... /** * OAuth 配置 * * scopes公众平台snsapi_userinfo / snsapi_base开放平台snsapi_login * callbackOAuth 授权完成后的回调页地址 */ oauth [ scopes [snsapi_userinfo], callback /examples/oauth_callback.php, ], // ... ]; $app new Application($options);配置项说明oauth.scopes数组类型声明授权时需要的权限范围。公众号可选snsapi_userinfo弹出确认页、返回用户资料或snsapi_base静默授权、仅返回openid开放平台网页登录场景下为snsapi_login。oauth.callback授权完成后的回调地址未编码的相对 URLSDK 在构造授权跳转链接时会自动处理拼接与编码。配置文档还特别提到了一个多商户/子商户场景下的动态修改技巧在 Application 实例化完成后可以通过$app[config]-set(oauth.callback, wechat/oauthcallback/. $sub_merchant_id-id);动态修改回调地址从而在同一个服务商配置下区分不同子商户的授权来源。SDK 中 OAuth 模块的 API在 SDK 中我们使用名称为oauth的模块来完成授权服务主要用到两个 API发起授权与获取已授权用户。发起授权$response $app-oauth-scopes([snsapi_userinfo]) -redirect();当你的应用是分布式架构且没有会话保持的情况下你需要自行设置请求对象以实现会话共享。比如在 Laravel 框架中支持 Session 储存在 Redis 中那么需要这样$response $app-oauth-scopes([snsapi_userinfo]) -setRequest($request) -redirect(); // 回调后获取 user 时也要设置 $request 对象 // $user $app-oauth-setRequest($request)-user();$response的返回值是一个Symfony\Component\HttpFoundation\RedirectResponse实例。你可以根据所用框架的响应机制做出正确处理在要求返回响应值的框架如 Laravel 控制器中直接return $response;在直接echo或$this-display()的框架如 Yii2中则使用$response-send();。版本演进提示在 5.x / 6.x 文档中redirect()的返回值已从RedirectResponse对象演进为字符串跳转地址需要自行完成跳转例如header(Location: {$redirectUrl})或 Laravel 的return \redirect($redirectUrl);。同时 5.x 起支持在redirect($request-fullUrl())中直接指定回调 URL 为当前页面。获取已授权用户$user $app-oauth-user();$user是Overtrue\Socialite\User对象可以调用的方法如下方法说明$user-getId()对应微信的 OPENID$user-getNickname()对应微信的 nickname$user-getName()对应微信的 nickname$user-getAvatar()头像网址$user-getOriginal()原始 API 返回的结果3.x/4.x5.x 起更名为getRaw()$user-getToken()access_token比如用于地址共享时使用5.x 起为getAccessToken()$user-getRefreshToken()refresh_token5.x 起提供$user-getExpiresIn()expires_inAccess Token 过期时间5.x 起提供$user-getTokenResponse()返回access_token时的响应值5.x 起提供两个必须牢记的要点$user里没有openid字段$user-id便是openid想拿微信返回的原样全部信息请使用$user-getOriginal()5.x 起为getRaw()当scope为snsapi_base时$oauth-user()返回的对象里只有id没有其它信息——这是静默授权的天然限制。版本演进提示5.x/6.x 中获取已授权用户的入口改为$user $oauth-userFromCode($code);其中$code取自微信回调 URL 携带的code即$_GET[code]。6.x 中模块访问方式也统一为$app-getOAuth()。源码层面的实现解析从当前仓库源码可以印证上述 API 的底层实现。在 src/OfficialAccount/Application.php 中getOAuth()基于overtrue/socialite的WeChatProvider 构造 OAuth 客户端public function getOAuth(): SocialiteProviderInterface { if (! $this-oauthFactory) { $this-oauthFactory fn (self $app): SocialiteProviderInterface (new WeChat( [ client_id $this-getAccount()-getAppId(), client_secret $this-getAccount()-getSecret(), redirect_url $this-config-get(oauth.redirect_url), ] ))-scopes((array) $this-config-get(oauth.scopes, [snsapi_userinfo])); } $provider call_user_func($this-oauthFactory, $this); // ... 校验必须是 SocialiteProviderInterface 实例 return $provider; }由此可以确认几个实现事实OAuth 模块本质上就是overtrue/socialite的微信 Provider 封装client_id/client_secret分别取自公众号账户的app_id/secret默认 scope 为[snsapi_userinfo]若未配置oauth.scopes则按此默认值执行配置键在新版本中为oauth.redirect_url与 3.x 文档的oauth.callback键名不同使用时请以所用版本为准框架还提供了setOAuthFactory(callable $factory)方法src/OfficialAccount/Application.php允许你完全替换默认的 OAuth Provider 构造逻辑实现深度定制。依赖关系上composer.json 声明了对overtrue/socialite: ^3.5.4|^4.0.1的依赖这就是$user对象方法getId、getNickname、getRaw等的来源。另外6.x 版本的公众号模块文档docs/src/6.x/official-account/index.md也明确说明通过$oauth $app-getOAuth();获取该模块。网页授权完整实例下面用原生 PHP 写法演示完整落地。假设oauth_callback是我们的授权回调 URL未 urlencode 编码user/profile是需要授权才能访问的页面。业务页面http://easywechat.com/user/profile?php use EasyWeChat\Foundation\Application; $config [ // ... oauth [ scopes [snsapi_userinfo], callback /oauth_callback, ], // .. ]; $app new Application($config); $oauth $app-oauth; // 未登录 if (empty($_SESSION[wechat_user])) { $_SESSION[target_url] user/profile; return $oauth-redirect(); // 这里不一定是 return如果你的框架 action 不是返回内容的话你就得使用 // $oauth-redirect()-send(); } // 已经登录过 $user $_SESSION[wechat_user]; // ... 正常渲染业务页面授权回调页http://easywechat.com/oauth_callback?php use EasyWeChat\Foundation\Application; $config [ // ... ]; $app new Application($config); $oauth $app-oauth; // 获取 OAuth 授权结果用户信息 $user $oauth-user(); $_SESSION[wechat_user] $user-toArray(); $targetUrl empty($_SESSION[target_url]) ? / : $_SESSION[target_url]; header(location:. $targetUrl); // 跳转到 user/profile流程闭环业务页检测未登录 → 记录target_url并跳微信授权 → 微信回调oauth_callback携带code→ 回调页用$oauth-user()换取用户信息写入 SESSION → 跳回target_url。版本适配提示若使用 5.x/6.x上述代码中回调页取用户应改为$user $oauth-userFromCode($_GET[code]);跳转前自行header(Location: ...)5.x 文档特别提醒若回调code来源于静默授权应显式$oauth-scopes([snsapi_base])后再调用userFromCode()否则默认会走snsapi_userinfo逻辑。会话保持与注意事项上面的例子都基于$_SESSION保持会话。在微信客户端中你也可以结合 COOKIE 来存储登录态但需要注意不同平台 Cookie 的有效期不同Android 的失效会相对快一些不过对绝大多数场景已经够用。最后补充几点实战注意事项域名配置必须精确匹配公众号后台配置的授权域名必须与回调 URL 所在域名完全一致含子域级别否则授权会被微信拒绝code是一次性的每次授权生成的code只能换取一次access_token且有时效回调处理务必及时snsapi_base与snsapi_userinfo的选择只需要识别用户如免登录用snsapi_base静默、无感知需要展示昵称头像等资料时用snsapi_userinfo会弹出授权确认页state参数OAuth 流程中的state参数可携带自定义状态用于防 CSRF 与上下文传递socialite 提供了对应的 state 机制可在回调中校验其一致性版本间 API 差异从 3.x 的$app-oauth-user() 返回RedirectResponse到 5.x 的userFromCode($code) 返回跳转字符串再到 6.x 的$app-getOAuth()使用前务必确认所安装版本对应的调用方式可分别对照仓库中的 4.x、5.x、6.x 版本文档。参考阅读本模块基于overtrue/socialite实现$user对象更丰富的接口能力可查阅该扩展包文档更多微信网页授权 API 细节可查阅微信公众平台官方文档网页授权、开放平台网页登录两篇配置项的完整列表见 docs/src/3.x/configuration.md模块源码见 src/OfficialAccount/Application.php。赞分享后端即时通讯【免费下载链接】easywechat 一个 PHP 微信 SDK项目地址https://gitcode.com/gh_mirrors/ea/easywechat点击查看免费下载相关推荐WeKnora 消息管理 API 实战指南历史消息加载、删除、搜索与聊天历史知识库统计WeKnora 消息管理 API 实战指南历史消息加载、删除、搜索与聊天历史知识库统计 消息管理 API 是 WeKnora 对话体系RAG 问答、Agen后端即时通讯EasyWeChat 微信公众号网页授权OAuth2.0实战指南从授权流程到 SDK 源码解析EasyWeChat 微信公众号网页授权OAuth2.0实战指南从授权流程到 SDK 源码解析 公众号网页授权OAuth 2.0是每一个微信 Web后端即时通讯EasyWeChat 公众号 JSSDK 网页开发buildConfig 签名配置实战指南EasyWeChat 公众号 JSSDK 网页开发buildConfig 签名配置实战指南 本篇技术指南围绕 EasyWeChatPHP 微信 SDK中公后端即时通讯上一篇StarRocks substring_index 字符串函数详解语法、语义与底层实现下一篇如何在3分钟内实现iOS设备虚拟定位iFakeLocation跨平台解决方案深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考