微信公众平台开发 - OAuth2.0 网页授权接口, 网页授权接口详解(含源码)
作者: 孟祥磊 https://home.cnblogs.com/u/mxlbook/ -微信公众平台开发实例教程 https://item.jd.com/12041625.html
在微信开发的高级应用中, 几乎都会使用到该接口, 因为通过该接口, 可以获取到用户的微信基础信息, 其中的用户唯一标识 OpenID 是微信应用中最长用到的参数之一, 近期有很多学员一直咨询, 所以我写下这篇文章.
1. 网页授权接口的作用
开发者通过网页授权接口, 可获取到用户的基本信息, 包括 OpenID, 昵称, 用户资料填写的省份, 城市, 国家以及头像地址, 以实现业务逻辑.
与同样是获取用户基本信息的用户管理中的 "获取用户信息" 接口相比, 网页授权接口无论用户是否关注了公众号, 都可以正常获取到用户信息, 而用户管理中的 "获取用户信息" 接口则必须关注公众号才可获取.
2. 网页授权接口模式介绍
微信公众平台网页授权接口有两种模式, 分别是 scope 为 snsapi_base 和 scope 为 snsapi_userinfo, 根据微信应用的不同需求, 会用到不同的模式, 两种模式各有利弊.
(1)以 snsapi_base 为 scope 发起的网页授权.
l 优点: 静默授权, 直接跳转到到回调页, 不会弹出 "确认登陆" 页面, 用户感知较好
l 缺点: 仅可获取到用户的 OpenID, 在需要获取其他用户信息时不适用
(2)以 snsapi_userinfo 为 scope 发起的网页授权.
l 优点: 除用户 OpenID 外, 还可以获取到用户的, 昵称, 用户资料填写的省份, 城市, 国家以及头像地址
l 缺点: 用户进入页面时会弹出 "确认登陆" 也就是同意授权的页面, 单击 "确认登陆" 按钮后, 才会跳转到回调页, 用户感知较差
注意: 对于已关注该公众号的用户, 如果从公众号的回话或者自定义菜单进入本公众号的网页授权页, 即使是以 snsapi_userinfo 为 scope 发起的网页授权, 也是静默授权, 不会弹出 "确认" 登陆界面.
3. 数据传输流程解析
以 snsapi_base 为 scope 发起的网页授权, 当用户进入使用网页授权的网页时, 会带上 code 参数, 通过该参数, 并调用接口, 可获取到一个特殊的 access_token 以及用户的 OpenID, 程序可根据该参数继续运行, 流程如图所示.
以 snsapi_userinfo 为 scope 发起的网页授权, 与以 snsapi_base 为 scope 发起的网页授权不同的是, 首先会进入 "确认登陆", 也就是授权页面, 用户同意授权后, 会跳转到回调页, 并带上 code 参数, 通过该参数, 并调用接口, 可获取到一个特殊的 access_token 以及用户的 OpenID, 此时, scope 为 snsapi_userinfo 时, 即可通过 access_token 和 OpenID 获取用户的基本信息了.
4. 网页授权接口注意事项
(1)网页授权接口暂时只支持认证后的服务号调用.
(2)在微信公众号调用用户网页授权接口之前, 开发者需要先到公众平台官网中的 "开发 接口权限 网页服务 网页帐号 网页授权获取用户基本信息" 的配置选项中, 配置授权回调域名, 如图所示. 请注意, 这里填写的是域名(是一个字符串), 而不是 URL, 因此请勿加 http:// 等协议头.
(3)授权回调域名配置规范为全域名, 比如需要网页授权的域名为: www.qq.com, 如图所示, 配置以后此域名下面的页面 http://www.qq.com/music.html , http://www.qq.com/login.html 都可以进行 OAuth2.0 鉴权. 但 http://pay.qq.com , http://music.qq.com , http://qq.com 无法进行 OAuth2.0 鉴权.
(4)回调页面域名需使用字母, 数字及 "-" 的组合, 不支持 IP 地址, 端口号及短链. 填写的域名需与实际回调 URL 中的域名相同. 填写的域名须通过 ICP 备案的验证.
5.scope 参数为 snsapi_base 的网页授权接口调用实例
步骤
(1)获取 code
(2)通过 code 换取 access_token 以及 OpenID
(1)获取 code
在确保微信公众账号拥有授权作用域 scope 参数为 snsapi_base 的前提下, 引导微信用户打开如下格式页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
若提示 "该链接无法访问", 请检查参数是否填写错误, 是否拥有 scope 参数对应的授权作用域权限.
参数说明, 如表所示:
scope 为 snsapi_base 时接口调用参数说明
参数 | 是否必须 | 说明 |
appid | 是 | 公众号的唯一标识 |
redirect_uri | 是 | 授权后重定向的回调链接地址,请使用 urlencode 对链接进行处理 |
response_type | 是 | 返回类型,请填写 code |
scope | 是 | 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户 openid) |
state | 否 | 重定向后会带上 state 参数,开发者可以填写 a-zA-Z0-9 的参数值,最多 128 字节 |
#wechat_redirect | 是 | 无论直接打开还是做页面 302 重定向时候,必须带此参数 |
访问该链接后, 会跳转到回调页, 即 redirect_uri/?code=CODE&state=STATE, 如果回调页是 "http://www.xxx.qq/test.php",code 是微信自动分配的, 也就是上面链接中获取到的 response_type 的值, 每次访问都不同, 假设 code 为 "031cEhnA1qGrf10uzzoA1n3jnA1cEhn1" 回调页即为:
"http://www.xxx.qq/test.php/?code=031cEhnA1qGrf10uzzoA1n3jnA1cEhn1&state=STATE".
(2)通过 code 换取 access_token 以及 OpenID
回调页带上的 code 参数可通过 GET 方式获取, 即 $_GET['code']; 并通过指定接口地址获取 access_token 以及 OpenID.
接口调用地址:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
调用参数说明, 如表所示:
获取 access_token 以及 OpenID 调用参数说明
参数 | 是否必须 | 说明 |
appid | 是 | 公众号的唯一标识 |
secret | 是 | 公众号的 appsecret |
code | 是 | 填写第一步获取的 code 参数 |
grant_type | 是 | 填写为 authorization_code |
返回说明:
正常情况下, 微信会返回 JSON 数据包给公众号:
- { "access_token":"ACCESS_TOKEN",
- "expires_in":7200,
- "refresh_token":"REFRESH_TOKEN",
- "openid":"OPENID",
- "scope":"SCOPE" }
返回参数说明:
返回参数说明
参数 | 描述 |
access_token | 网页授权接口调用凭证, 注意:此 access_token 与基础支持的 access_token 不同 |
expires_in | access_token 接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新 access_token |
openid | 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的 OpenID |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误时微信会返回 JSON 数据包如下(示例为 Code 无效错误):
{"errcode":40029,"errmsg":"invalid code"}
5. 程序
- <?php
- /*
- 以 snsapi_base 为 scope 发起的网页授权
- 获取 access_token,openid
- */
- require('wei_function.php');
- $appid="wx78478e595939c538";
- $secret="5540e8ccab4f71dfad752f73cfb85780";
- $code=$_GET['code'];
- $OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
- $OAuthinfo=json_decode(getdata($OAuthurl),true);
- //print_r($OAuthinfo);
- $access_token=$OAuthinfo['access_token'];
- $openid=$OAuthinfo['openid'];
- echo "获取到的 access_token:<br />".$access_token."<br />";
- echo "获取到的用户 openid:<br />".$openid;
- ?>
代码解析
require('wei_function.php'); 该函数文件可以购买微信公众平台开发实例教程 https://item.jd.com/12041625.html , 在该书中第 95 页有详细讲解.
- $appid="xxx";
- $secret="xxx";
分别将公众号的 AppID 和 AppSecret 赋值给变量 $appid 和 $secret;
- $OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
- $OAuthinfo=json_decode(getdata($OAuthurl),true);
- $access_token=$OAuthinfo['access_token'];
- $openid=$OAuthinfo['openid'];
将接口地址中的 appid,secret 和 code 参数替换, 并通过 getdata()函数 (该函数在 wei_function.php 文件中, 可直接被使用) 请求该接口地址, 并将返回的 JSON 数据通过 json_decode()函数处理为数组, 之后单独输出 access_token 和 openid.
访问该程序的网址为: https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx78478e595939c538&redirect_uri=http://www.xxx.com/OAuth2.0.php&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
appid 为公众号的 appid, 且需与上面的 $appid 的值相同, 否则会提示 {"errcode":40029,"errmsg":"invalid code, hints: [ req_id: z3H9UA0717ns83 ]"} 这样的错误信息, 其代表的意思是不合法的 oauth_code.
OAuth2.0.php 为该程序文件.
运行效果如图所示.
6.scope 参数为 snsapi_userinfo 的网页授权接口调用实例
步骤
(1)获取 code
(2)通过 code 换取 access_token 以及 OpenID
(3)刷新 access_token(如果需要) https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.3382149958051741&token=&lang=zh_CN
(4)拉取用户信息 https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.3382149958051741&token=&lang=zh_CN
(1)获取 code
在确保微信公众账号拥有授权作用域 scope 参数为 snsapi_userinfo 的前提下, 引导微信用户打开如下格式页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
若提示 "该链接无法访问", 请检查参数是否填写错误, 是否拥有 scope 参数对应的授权作用域权限.
该链接格式与以 snsapi_userinfo 为 scope 发起的网页授权不同的仅仅是 scope 不同, 其余相同.
调用参数说明, 如所示:
scope 为 snsapi_userinfo 时接口调用参数说明
参数 | 是否必须 | 说明 |
appid | 是 | 公众号的唯一标识 |
redirect_uri | 是 | 授权后重定向的回调链接地址,请使用 urlencode 对链接进行处理 |
response_type | 是 | 返回类型,请填写 code |
scope | 是 | 应用授权作用域,snsapi_userinfo (弹出授权页面,可通过 openid 拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) |
state | 否 | 重定向后会带上 state 参数,开发者可以填写 a-zA-Z0-9 的参数值,最多 128 字节 |
#wechat_redirect | 是 | 无论直接打开还是做页面 302 重定向时候,必须带此参数 |
(2)通过 code 换取 access_token 以及 OpenID
该步骤与以 snsapi_userinfo 为 scope 发起的网页授权流程一致, 参考其调用方法即可.
(3)刷新 access_token(如果需要) https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.3382149958051741&token=&lang=zh_CN
由于 access_token 拥有较短的有效期, 当 access_token 超时后, 可以使用 refresh_token 进行刷新, refresh_token 有效期为 30 天, 当 refresh_token 失效之后, 需要用户重新授权.
refresh_token 在 (2) 通过 code 换取 access_token 以及 OpenID 中与 access_token 和 OpenID 一同获取, 获取代码为 $refresh_token=$OAuthinfo['refresh_token'];.
(4)拉取用户信息
- <?php
- /*
- 以 snsapi_base 为 scope 发起的网页授权
- 获取 access_token,openid
- */
- require('wei_function.php');
- $appid="wx78478e595939c538";
- $secret="5540e8ccab4f71dfad752f73cfb85780";
- $code=$_GET['code'];
- $OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
- $OAuthinfo=json_decode(getdata($OAuthurl),true);
- //print_r($OAuthinfo);
- $access_token=$OAuthinfo['access_token'];
- $openid=$OAuthinfo['openid'];
- $user_url="https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid."&lang=zh_CN";
- $user_info=json_decode(getdata($user_url),true);
- //print_r($user_info);
- echo "OpenID:".$user_info['openid'];
- echo "<br />";
- echo "昵称:".$user_info['nickname'];
- echo "<br />";
- echo "性别:".$user_info['sex'];
- echo "<br />";
- echo "资料填写城市:".$user_info['city'];
- echo "<br />";
- echo "资料填写省份:".$user_info['province'];
- echo "<br />";
- echo "资料填写国家:".$user_info['country'];
- echo "<br />";
- echo "用户头像地址:".$user_info['headimgurl'];
- echo "<br />";
- echo "unionid:".$user_info['unionid'];
- ?>
效果如图所示:
5. 本课内容已录制为视频教程, 视频已在微信公众平台开发实例教程 https://item.jd.com/12041625.html 一书中发布, 欢迎购买.
点此购买微信公众平台开发实例教程 https://item.jd.com/12041625.html
来源: http://www.92to.com/bangong/2018/05-31/33861416.html