「应对微信调整」从零到一快速实现一个微信公众号授权项目

前言

上一篇文章说到,微信官方团队发了一则公告,美其名曰:"为了优化开发体验,避免多个同一功能接口对开发者造成困扰,微信团队将对下发统一消息接口进行如下调整。" 正是由于这个调整,而将部分开发者带入了深渊!对于这个调整,众多的开发者褒贬不一。官方既然已经确定修改了,那么我们应当尽快的完成适配,以便于我们能正常的开发公众号和小程序应用。

关于微信官方团队发出的公告事宜的具体事项,有还未了解的同学可以浏览我之前的文章:

突发!如何应对微信小程序与公众号下发统一消息接口调整

本文将会对上一篇文章中提到的解决方案之一进行详细的实现:彻底解决方案

  1. 重新写个微信公众号 h5 页面,授权获取 jscode,再来换取公众号 openid。
  2. 使用 openid 按照文档下发微信公众号模版消息,点击消息打开对应的小程序进行查看。

开发前准备

由于"下发统一消息接口"影响的是微信小程序内推送到公众号的功能,因此要重新实现这一套,我将默认大家都已经申请了公众号小程序。如果你没有申请,确确实实是从零到一开发的,那么就简单看下面如何申请就可以了,很简单!

申请公众号

  1. 申请公众号开发者账号:前往 微信公众平台 申请公众号开发者账号,并完成账号认证。

  2. 配置公众号开发设置:登录微信公众平台,在"开发-基本配置"中配置好公众号的相关信息,包括服务器配置、公众号名称、AppID、AppSecret等。

申请小程序

  1. 申请小程序:前往 微信公众平台 | 小程序 申请小程序,具体可以按照页面引导操作

  2. 如果你已经认证了公众号,可以复用公众号的资质快速注册小程序,如下图所示:

进入开发阶段

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 绑定到自己的系统进行项目开发了,可以按照标准化的流程进行下发微信公众号模版消息了。

官方文档:微信网页开发 - 网页授权

相关推荐
熊的猫11 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
速盾cdn18 分钟前
速盾:vue的cdn是干嘛的?
服务器·前端·网络
四喜花露水1 小时前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy1 小时前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
瑶琴AI前端1 小时前
uniapp实现H5和微信小程序获取当前位置(腾讯地图)
微信小程序·小程序·uni-app
web Rookie1 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust2 小时前
css:基础
前端·css
帅帅哥的兜兜2 小时前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
yi碗汤园2 小时前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称2 小时前
购物车-多元素组合动画css
前端·css