前言
上一篇文章说到,微信官方团队发了一则公告,美其名曰:"为了优化开发体验,避免多个同一功能接口对开发者造成困扰,微信团队将对下发统一消息接口进行如下调整。" 正是由于这个调整,而将部分开发者带入了深渊!对于这个调整,众多的开发者褒贬不一。官方既然已经确定修改了,那么我们应当尽快的完成适配,以便于我们能正常的开发公众号和小程序应用。
关于微信官方团队发出的公告事宜的具体事项,有还未了解的同学可以浏览我之前的文章:
本文将会对上一篇文章中提到的解决方案之一进行详细的实现:彻底解决方案
- 重新写个微信公众号 h5 页面,授权获取 jscode,再来换取公众号 openid。
- 使用 openid 按照文档下发微信公众号模版消息,点击消息打开对应的小程序进行查看。
开发前准备
由于"下发统一消息接口"影响的是微信小程序内推送到公众号的功能,因此要重新实现这一套,我将默认大家都已经申请了公众号 和小程序。如果你没有申请,确确实实是从零到一开发的,那么就简单看下面如何申请就可以了,很简单!
申请公众号
-
申请公众号开发者账号:前往 微信公众平台 申请公众号开发者账号,并完成账号认证。
-
配置公众号开发设置:登录微信公众平台,在"开发-基本配置"中配置好公众号的相关信息,包括服务器配置、公众号名称、AppID、AppSecret等。
申请小程序
-
申请小程序:前往 微信公众平台 | 小程序 申请小程序,具体可以按照页面引导操作
-
如果你已经认证了公众号,可以复用公众号的资质快速注册小程序,如下图所示:
进入开发阶段
1. 创建网页授权链接
在公众号菜单设置或H5页面中,创建一个用于获取用户授权的链接。链接的格式如下:
ini
https://open.weixin.qq.com/connect/oauth2/authorize
?appid=APPID
&redirect_uri=REDIRECT_URI
&response_type=code
&scope=SCOPE
&state=STATE
#wechat_redirect
我们分析下上面的链接,其中主要的传递参数有:
- appid:公众号的AppID
- 公众号的唯一标识,可以在公众号后台获取到AppID
- redirect_uri:用户同意授权后的回调URL
- 授权后重定向的回调链接地址,需使用 urlEncode 对链接进行处理
- response_type:返回类型,固定填写code
- scope:应用授权作用域
- snsapi_base:不弹出授权页面,直接跳转,只能获取用户openid
- snsapi_userinfo:弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
- state:自定义参数
- 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
- #wechat_redirect:固定传递
- 必须带此参数
注意:因为我们仅仅需要获取到openid,所以我们不需要弹出授权页面拿到微信昵称、性别等资料。因此我们仅做静默授权获取code即可,这样实现起来比较简单
2. 用户授权并回调
用户在打开H5页面时,点击上一步生成的链接,会跳转到微信授权页面(我是用的静默授权),确认授权后,微信会跳转到上一步中指定的REDIRECT_URI,并携带一个code参数。
这时候我们需要解析一下URL,在回调的URL中,获取URL中的code参数。
3. 使用code换取openid
使用code换取用户的openid。可以使用服务器端的语言或框架来实现此步骤。可以通过以下API来换取openid:
ini
https://api.weixin.qq.com/sns/oauth2/access_token
?appid=APPID
&secret=APPSECRET
&code=CODE
&grant_type=authorization_code
其中,APPID 和 APPSECRET 分别为公众号的 AppID 和 AppSecret,CODE 为上一步获取到的 code参数。
尤其注意:由于公众号的secret安全级别都非常高,必须只保存在服务器,不允许传给客户端。因此不建议使用前端直接获取openid,建议使用后端语言实现此步骤。
4. 获取到openid
通过上一步的 API 调用,会返回一个包含 openid 的 JSON 数据。解析 JSON 数据,即可获取到用户的openid。
至此,我们就完成了openid的获取,可以正常的使用它进行推送开发了!
遇到的几个问题
1. 如何调试
其实调试问题,微信官方也已经考虑到了这个问题,在微信公众号的后台,他们提供了一下开发者工具,可以让我们在开发阶段进行便捷的测试,如下图所示:
在这里,我们主要使用的是 "公众平台测试账号" 这个工具,下面我们看一下这个工具是如何使用的。
- 第一步
点击 "公众平台测试账号" ,用自己微信扫码进行登录,然后就进入到了主页,在主页中我们可以看到给我们生成了测试的 appID 和 appsecret,这两个重要的参数以供我们测试授权使用
- 第二步
在当前页面中我们找到 "测试号二维码" 一栏,使用需要调试的微信扫码关注测试公众号,如下图所示:
- 第三步
在当前页面继续向下滚动页面,找到 "网页授权获取用户基本信息",点击修改,添加授权回调域名,如下图所示:
完成上面的两步后,我们就可以进行愉快的测试了,可以使用手机微信,或者是微信开发者工具进行调试!
注意:调试阶段,可以使用域名或IP都可以,在正式上线环境下,必须使用备案的域名才可以!
2. redirect_uri
- redirect_uri 必须提前在微信公众号后台中维护好授权回调域名,否则会报 "10003:redirect_uri域名与后台配置不一致"
- redirect_uri 必须使用 urlEncode 进行编码处理
- 使用 Vue 框架开发的,建议使用 history 路由模式,可以避免微信回调链接的各种参数拼接问题
- 使用 Vue 开发时,如果你非要使用 hash 路由模式,也不是不可以解决,只能在路由拦截器中处理一下 # 拼接的问题,重新整理成正确的路由链接就可以了
3. 重定向循环问题
在开发调试的过程中遇到了这样一个问题,授权完成后,返回重定向页面,进入了死循环?结果就是关闭不了了,这是为什么呢?我猜测这是微信浏览器自己的bug,不过时隔多年,微信并没有解决它。
以上面的页面跳转流程图为例,授权完成后,路由栈应该为只有页面C,但结果却不是这样的。
结果是存在两个路由:页面A、页面C,在页面C中点返回,则返回到了页面A,页面A会自动授权,则又进行了上述流程图的步骤,如此循环往复,结果就是退不出去!
如何做呢?总不能让用户手动关闭浏览器吧?
解决方案:我只能在页面C 中添加一个按钮 - "返回",点击返回可自动退出,解决了重定向问题。如果你有更好的实现方案,欢迎说来听听。
接下来我们实现这个返回功能就行了,WeixinJSBridge 提供了关闭浏览器的 API,下面是我自己的实现代码。
js
<template>
<div class="back-view">
<div v-if="isWeixin" class="back-text" @click="close"> <icon name="arrow-left"></icon> 返回 </div>
</div>
</template>
<script>
export default {
methods: {
// 关闭微信浏览器
close() {
if (WeixinJSBridge) {
try {
WeixinJSBridge.call('closeWindow')
} catch (error) {}
}
},
// 判断是否为微信浏览器环境
isWeixin() {
return typeof WeixinJSBridge === 'object' && typeof WeixinJSBridge.invoke === 'function'
}
}
}
</script>
<style lang="scss" scoped>
.back-view {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 15px 20px;
background-color: $color-primary;
}
.back-text {
color: white;
font-weight: bold;
font-size: 16px;
}
</style>
小结
至此,我们快速的完成了从零到壹实现一个微信公众号授权项目,成功的获取到了微信公众号的 openid,我们可以愉快的使用 openid 绑定到自己的系统进行项目开发了,可以按照标准化的流程进行下发微信公众号模版消息了。