导读:本期聚焦于唐振业创作的《微信公众号网页授权scope从snsapi_base升级到userinfo的完整流程详解》,敬请观看详情。网页授权接口中scope参数选snsapi_base还是snsapi_userinfo,直接决定了能否拿到用户昵称和头像。snsapi_base静默授权只能获取openid,适合免打扰场景;而要展示用户资料、做个性化推荐时,就必须升级到snsapi_userinfo弹出授权界面。本文详细讲解两种模式的区别、授权链接构造、code换access_token、刷新令牌、拉取用户信息的完整接口调用流程,并附上PHP服务端代码示例与常见错误排查,帮助你顺利完成scope升级改造。

微信公众号开发中,网页授权是获取用户身份最常用的手段。很多项目最初为了体验流畅,选择snsapi_base静默授权,只拿一个openid就够用了。随着业务发展,需要在页面上展示用户昵称、头像,甚至做个性化推荐时,就必须把scope升级为snsapi_userinfo。这个升级看似只改一个参数,实际涉及授权链接调整、用户确认、接口调用链路变化等多个环节,处理不当容易出现40029、10005等错误码。本文将从原理到代码,完整梳理升级流程。

微信公众号网页授权scope从snsapi_base升级到userinfo的完整流程详解

一、先搞清楚snsapi_base和snsapi_userinfo的本质区别

网页授权本质上是OAuth2.0协议的一种实现,scope参数决定了授权的深度。snsapi_base是基础授权,用户完全无感知,页面不会弹出任何确认框,授权后只能拿到openid,适用于登录态识别、记录访问等对用户信息无要求的场景。

snsapi_userinfo则是完整授权,用户首次进入时会弹出授权确认页面,用户点击同意后,除了openid,还可以通过接口拉取昵称、头像、性别、所在城市等信息。需要特别注意:必须是关注了公众号的用户,或者用户主动同意过授权,才能成功拉取userinfo,否则接口会返回错误。

两者的授权链接格式完全相同,区别只在scope参数取值。还有一个关键点是access_token的概念区分:网页授权的access_token和基础支持的access_token(调用全局接口用的那个)是两个完全不同的东西,不能混用,缓存的key一定要分开存储,这是升级改造时最容易踩的坑。

二、升级后完整的授权流程与接口调用

升级到snsapi_userinfo后,整个授权链路变成四步:构造授权链接跳转、通过code换取access_token和openid、必要时刷新access_token、拉取用户信息。下面逐步展开。

第一步,构造授权链接并引导用户跳转。授权地址格式如下:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

其中redirect_uri需要经过urlencode处理,state可以用于携带业务参数或防CSRF校验。注意末尾的#wechat_redirect必须保留,且必须放在#前使用&拼接参数。跳转后用户看到授权确认页,点击同意,微信会携带code和state重定向回你配置的回调地址。

第二步,用code换取网页授权access_token。code是一次性凭证,有效期只有5分钟,且只能消费一次,务必在回调处理中立即使用。接口调用示例如下:

<?php
$code = $_GET['code'];
$appid = '你的AppID';
$secret = '你的AppSecret';

// 用code换取网页授权access_token和openid
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?" .
       "appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";

$res = json_decode(file_get_contents($url), true);

if (isset($res['errcode'])) {
    // 常见错误:40029 code无效,40163 code已被使用
    exit('授权失败:' . $res['errmsg']);
}

$access_token = $res['access_token'];
$openid      = $res['openid'];
$refreshToken = $res['refresh_token']; // 建议入库保存

第三步,拉取用户信息。拿到access_token和openid后,调用userinfo接口即可获取详细资料:

<?php
$infoUrl = "https://api.weixin.qq.com/sns/userinfo?" .
           "access_token={$access_token}&openid={$openid}&lang=zh_CN";

$userInfo = json_decode(file_get_contents($infoUrl), true);

// 返回字段:openid、nickname、sex、province、city、headimgurl等
// snsapi_base模式下调用此接口会返回errcode 10005
var_dump($userInfo);

第四步,关于access_token的刷新。网页授权access_token有效期约2小时,refresh_token有效期30天。refresh_token在30天内可以重复使用刷新,刷新后会获得新的access_token和新的refresh_token。如果用户授权超过30天,则需要重新走一遍授权流程。因此建议把openid、access_token、refresh_token以及过期时间一起存入数据库,避免频繁要求用户重新授权。

三、升级改造的代码策略与降级容错

直接把代码里的scope常量改掉是最简单的做法,但更稳妥的方案是设计一个兼容两种模式的授权入口。对于已授权过的老用户,可以先尝试用缓存中的用户资料判断是否已授权userinfo;对于未授权的用户,再跳转snsapi_userinfo授权链接,这样能减少不必要的弹窗打扰。

改造时的参考实现:

<?php
function buildAuthUrl($appid, $redirectUri, $scope, $state = 'state')
{
    $encodedUri = urlencode($redirectUri);
    $scope = in_array($scope, ['snsapi_base', 'snsapi_userinfo']) ? $scope : 'snsapi_base';
    return "https://open.weixin.qq.com/connect/oauth2/authorize" .
           "?appid={$appid}&redirect_uri={$encodedUri}" .
           "&response_type=code&scope={$scope}&state={$state}#wechat_redirect";
}

// 业务入口:先静默拿openid,再判断是否需要升级授权
$authUrl = buildAuthUrl($appid, 'https://你的域名/callback.php', 'snsapi_userinfo');
header('Location: ' . $authUrl);

此外要做降级容错:如果用户在授权页点击拒绝,回调不会携带code而是携带auth_referer等参数,代码里要能识别并给用户友好的提示页面,而不是直接报错。同时,由于2021年底微信调整了用户信息接口策略,未关注公众号的用户即使授权成功,拉取到的昵称和头像也可能为空,业务上要有兜底处理,例如提供默认头像和默认昵称。

四、常见错误码排查清单

升级过程中最容易遇到的几个错误如下:

  • 40029 invalid code:code无效或已过期,通常是本地调试时code被重复使用,或回调处理中code被消费了两次。
  • 40163 code been used:code只能使用一次,检查是否存在页面刷新导致重复请求的问题。
  • 10005 user not subscribe:用snsapi_base的access_token去调userinfo接口,必须升级scope后重新授权。
  • 10003 redirect_uri域名与后台配置不一致:检查公众号后台网页授权域名配置,域名必须与redirect_uri的域名完全一致,且不需要加http协议头。
  • 48001 api unauthorized:接口未授权,检查公众号类型,订阅号未认证时部分接口受限。

排查这类问题的通用方法是打印每一步接口的原始返回值,确认请求参数是否正确拼接。特别注意redirect_uri的urlencode只做一次,不要二次编码,否则微信会报重定向参数错误。

总体来说,从snsapi_base升级到snsapi_userinfo的核心工作在于:修改授权链接的scope参数、走完code换token的流程、调用userinfo接口拿资料,并把refresh_token持久化以便长期使用。配合合理的缓存与降级策略,升级改造可以在不影响老用户的情况下平滑完成。

微信公众号网页授权snsapi_userinfoOAuth2.0授权修改时间:2026-08-31 13:29:02

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。