详解Vue微信公众号开发踩坑全记录

本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记。

需求

  • 微信授权登录(基于公众号的登录方案)
  • 接入JS-SDK实现图片上传,分享等功能

现状及难点

  • 采用的Vue框架,前后端分离模式(vue工程仅作为客户端),用户通过域名访问的是客户端,但是微信授权中涉及签名和token校验依赖服务端
  • JS-SDK需要向服务端获取签名,且获取签名中需要的参数包括所在页面的url,但由于单页应用的路由特殊,其中涉及到IOS和android微信客户端浏览器内核的差异性导致的兼容问题

解决方案

授权登录

授权流程如下:

详细说明:

  1. 用户访问网站主域名
  2. vue客户端(domain/)接收请求,在路由解析前判断用户是否登录(比如检查cookie);
  3. 如果没有登录,则通过api获取微信授权地址,获取后跳转到微信服务端授权页面;
  4. 用户确认授权,微信服务器发起回调请求,这时需要回调到服务器端(domain/api/xxx)
  5. 服务器端保存用户信息,进行注册登录操作(记录cookie),重定向到vue客户端(domain/)
  6. 重复第一步,授权登录成功

踩坑记录:

以下是一个错误授权方案

这个方案为什么错误呢?其实如果只实现授权登录到话,这个方案是可以的,而且也很清晰,vue客户端单方面在服务器和微信服务器之间进行通信,微信服务器不能直接和服务器通信。这种方案的坑在于当微信授权回调时会携带一个code参数,该参数会污染vue路由导致ios上进行JS-SDK签名时失败(后续会具体描述这个问题)

JS-SDK签名

对于签名,官方是这么说的

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用

vue中路由有history和hash两种模式;在history模式下,理想的设计方案是,当进入到需要用到JS-SDK组件时,获取以下当前url(也就是通过 location.href.split(‘#')[0]获得到的地址)传递到服务端进行签名,应该就没问题了,但是IOS获取的url并不是调用微信js的时候所在页面的地址,而是进入到网站第一个页面的地址。

网上查询到一个方案是针对ios设备进入页面时先将当前url记录下来,到授权页面时将记录的url传递给服务端进行签名。该方案经实践是可行的,妈妈再也不用担心我的网址很丑很难看啦。

另外一个方案就是使用hash模式,这种模式下,url永远都只是主域名地址,省去了传递url的烦恼,也没必要处理兼容,所以如果不建议路由中有#的话,该方案应该是首选方案。

这里还有一个深坑,那就是如果授权方案采用了上述中的vue客户端处理回调的方式,那么ios将永远无法签名成功,为什么呢,因为这种方案路由通常是这样子的:

http://domain.com/?code=xxxxxx&stat=#/xxx

这种路由中带了参数的url是没法签名校验成功的!
这种路由中带了参数的url是没法签名校验成功的!
这种路由中带了参数的url是没法签名校验成功的!
重要的事情得说三遍啊

Coding

任何不上代码的吹逼都是耍流氓,这里笔者分享下在vue中具体怎么coding的。

微信授权登录

笔者在项目中使用的vue-router进行路由控制,使用了vuex记录用户登录信息,但是由于vuex中存储的内容在页面刷新后会丢失,所以服务端同时也写了用户登录状态到cookie中,vue中需要通过这两个条件进行登录判断,不多BB,直接看代码吧

// ... other code

router.beforeEach((to, from, next) => {
 if ((!VueCookie.get('user') && !store.state.userInfo)) {
  // 第一次访问
  console.log('授权登录')
  // 跳转到微信授权页面,微信授权地址通过服务端获得
  axios.post('/api/login').then(res => {
   var data = res.data
   if (data.code === 100) {
    window.location.href = data.data
   }
  })
 } else if (!store.state.userInfo) {
  // 刷新页面,获取数据存入vuex
  axios.get('/api/currentuser').then(res => {
   if (res.data.code === 100) {
    store.dispatch('setUserInfo', res.data.data)
    next()
   }
  })
  console.log('cookie生效期内登录')
  next()
 } else {
  // 已经登录
  console.log('已登录')
  next()
 }
})

//... other code

history模式下的JS-SDK签名

在入口文件中将当前url存入vuex

// ... other code
router.beforeEach((to, from, next) => {
 document.title = to.meta.title
 // 处理jssdk签名,兼容history模式
 if (!store.state.url) {
  store.commit('setUrl', document.URL)
 }
 // ... other code

在需要获取签名的组件中获取并进行配置

// ... other code
created () {
   var sef = this
   var url = ''
   // 判断是否是ios微信浏览器
   if (window.__wxjs_is_wkwebview === true) {
    url = this.$store.state.url.split('#')[0]
   } else {
    url = window.location.href.split('#')[0]
   }
   this.$http.get('/api/jssdk?url=' + url).then(function (res) {
    sef.lists = res.data.data
    hmTools.wechact(sef.lists, sef) //js-sdk配置
   })
  }
// ...other code

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 巧用Vue.js+Vuex制作专门收藏微信公众号的app

    本文一步一步教大家如何利用Vue.js + Vuex制作专门收藏微信公众号的app 项目地址: https://github.com/jrainlau/wechat-subscriptor 下载&运行 git clone git@github.com:jrainlau/wechat-subscriptor.git cd wechat-subscriptor && npm install npm run dev   // run in dev mode cd backend-serv

  • 详解Vue微信公众号开发踩坑全记录

    本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记. 需求 微信授权登录(基于公众号的登录方案) 接入JS-SDK实现图片上传,分享等功能 现状及难点 采用的Vue框架,前后端分离模式(vue工程仅作为客户端),用户通过域名访问的是客户端,但是微信授权中涉及签名和token校验依赖服务端 JS-SDK需要向服务端获取签名,且获取签名中需要的参数包括所在页面的url,但由于单页应用的路由特殊,其中涉及到IOS和android微信客户端浏览器内核的差异性导致的兼容问题 解决方案

  • 详解nodejs微信公众号开发——2.自动回复

    上一篇文章:nodejs微信公众号开发(1)接入微信公众号,本篇文章将在此基础上实现简单的回复功能. 1. 接入代码的优化 之前我们简单粗暴的实现了微信公众号的接入,接入的代码直接写在了app.js文件里面,从项目开发的角度而言,不便于日后代码的维护,所以将这部分代码独立出来,按照koa的风格,写成一个中间件. 在根目录下新建wechat文件夹,新建generator.js文件, var sha1 = require('sha1'); module.exports = function(opts

  • 详解nodejs微信公众号开发——6.自定义菜单

    上一篇文章:nodejs微信公众号开发--5.素材管理接口,我们实现了新增临时素材.管理永久素材的接口,这些接口的实现,使我们能够推送多样的消息给用户.本节介绍的内容是关于自定义菜单 1. 自定义菜单的介绍 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能.关于自定义菜单需要掌握以下几点内容: 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单. 一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以"..."代替. 创建自定义菜单后,由于微信客

  • 详解nodejs微信公众号开发——3.封装消息响应模块

    上一篇文章:nodejs微信公众号开发(2)自动回复,实现了简单的关注回复.采用拼接字符串的形式,并不是很方便,这里我们将其封装承接口. 1. ejs模板引擎 不使用拼接字符串的方式,那么模板引擎就是较好的选择.Nodejs开源模板的选择很多,程序中使用 EJS,有Classic ASP/PHP/JSP的经验用起EJS来的确可以很自然,也就是说,你能够在 <%...%> 块中安排 JavaScript 代码,利用最传统的方式 <%=输出变量%>(另外 <%-输出变量是不会对

  • 详解nodejs微信公众号开发——4.自动回复各种消息

    上一篇文章:nodejs微信公众号开发--3.封装消息响应模块,实现了对消息接口的模块化处理,方便后期的使用,本篇文章将介绍微信公众号回复各种消息的功能实现,包括文本.图片.语音.视频.音乐.图文等. 注:感觉最近localtunnel很不稳定,测试起来比较麻烦,有条件的自己搞个云服务器吧,我比较偷懒,几继续使用localtunnel了. 1. 被动回复用户消息 当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML

  • 详解nodejs微信公众号开发——1.接入微信公众号

    接入微信公众号是开发的第一步,万事开头难,走好第一步,后面的路就更宽广. 1.公众平台测试帐号的使用 登录微信公众平台,由于很多开发人员并没有认证的的微信公众号,所以比较折中的方式是使用公众平台测试帐号来测试功能,其优势是能够测试微信公众号的绝大部分功能,不受认证门槛的限制. 进入测试账号管理界面: 我们需要配置接口的信息,URL和Token是微信公众平台和本地开发服务建立连接的桥梁. 微信配置好后,扫面下方的测试号二维码,即可以在手机上测试开发的功能. 2.验证公众号 一图胜千言.接入公众号时

  • 详解nodejs微信公众号开发——5.素材管理接口

    上一篇文章:nodejs微信公众号开发--4.自动回复各种消息,我们实现了被动回复文字和图文,回复图片失败,因为需要先获取通过素材管理接口上传多媒体文件而得到的MediaId,这一节们就来实现素材管理的接口.可参看:公众平台开发者文档 1. 新增临时素材 临时素材顾名思义是临时的,上传后一定时间就被清理掉,适用于一些有时效性的图文链接.关于临时素材需要注意的点: 对于临时素材,每个素材(media_id)会在开发者上传或粉丝发送到微信服务器3天后自动删除(所以用户发送给开发者的素材,若开发者需要

  • vue中使用微信公众号js-sdk踩坑记录

    最近又在vue中捣鼓了下微信公众号api的接入,不得不说这里边水是真的深啊,上次分享了微信授权登录和js-sdk签名的部分,其中很多朋友私信我表示了疑惑,今天我就再次尝试理顺一下这里边的坑吧: 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微信分享.扫一扫.卡券.支付等微信特有的能力,为微信用户提供更优质的网页体验. 分享页面到朋友圈 上文是从官方文档

  • 详解nuxt 微信公众号支付遇到的问题与解决

    背景:nuxt为默认的history模式,用这个npm 支付weixin-js-sdk,开启debug模式,尽量在ios下调试,因为alert弹窗的信息会更多. async onPay (config) { try { const wxUrl = window.location.href//分享的路径 const res = await $axios.$get("")//获取配置sdk参数,包括微信分享的参数 if (res.status === 0) { const {data} =

  • php微信公众号开发模式详解

    学习步骤:分四章来讲述这部分内容,下面是每章的大致内容. 1.了解开发模式与编辑模式,开发前的一些准备. 2.开发模式用户.微信服务器.个人服务器是如何交互的.什么是接口. 3.各种接口功能的调用与实现. 4.js-SDK的调用 微信公众号开发两种模式:编辑模式和开发模式.编辑模式比较简单,你不需要操作任何的代码,只需要借助微信提供的功能来管理自己的微信公众号.这种方式开发的页面比较简单,主要用来实现文章的推送等功能.开发者模式则能通过自己的后台服务器与微信关注用户实现更多的交互作用,调用微信的

随机推荐