SPA单页面应用微信授权

基于单页面应用开发了几个微信公众号,梳理下微信公众号网页开发授权流程以便日后查阅。

概述

  • 前端框架为vue
  • 后端只提供api接口,不涉及任何页面编写
  • api通信认证方式为JWT。
  • Tips: 前端auth页面可以插播广告

授权流程

SPA微信授权流程图.jpg

前端处理

  • 前端使用vue-router,在router.beforeEach钩子中对每一个页面(url)做过滤。
  • 判断当前请求是否需要登陆,当前用户的登陆状态(即缓存中是否存在token)。缓存使用的good-storage, vuex
  • 若需要登陆则缓存当前web_url,并跳转微信授权地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect。其中,url参数REDIRECT_URI为后端callback接口地址。
  • router.beforeEach代码
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 微信浏览器打开
    let ua = window.navigator.userAgent.toLowerCase()
    let uaMatch = ua.match(/MicroMessenger/i)
    if (!uaMatch || uaMatch[0] !== 'micromessenger') {
      alert('请在微信客户端打开')
      return false
    }
    // 未登录的需要保存当前url,跳转到微信授权页面
    if (!auth.loggedIn()) {
      saveBeforeLoginUrl(to.fullPath)
      // 微信授权地址配置在prod.env.js中
      window.location.href = process.env.WECHAT_AUTH_URL
      return false
    }
    next()
  } else {
    next() // 确保一定要调用 next()
  }
})
  • 路由详情中配置requiresAuth标识是否需要登陆,示例代码如下:
export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      meta: {
        title: '首页'
      }
    }, {
      path: '/user',
      name: 'User',
      component: User,
      meta: {
        title: '用户中心',
        // requiresAuth设置为true时,需要登陆
        requiresAuth: true
      }
    }
  ]
})
  • 后端callback接口完成业务逻辑后,会重定向到前端auth页面。auth页面负责存储token,然后读取本地缓存的web_url,并跳转到web_url。auth页面代码:
<script>
  import { mapMutations } from 'vuex'
  import { getBeforeLoginUrl, saveBeforeLoginUrl } from 'common/cache'
  export default {
    name: 'Storage',
    data () {
      return {
        token: this.$route.query.token
      }
    },
    methods: {
      ...mapMutations(['changeUserToken'])
    },
    mounted () {
      if (!this.token) {
        alert('token参数为空')
        return
      }
      // 缓存token
      this.changeUserToken(this.token)
      // 页面恢复(进入用户一开始请求的页面)
      let url = getBeforeLoginUrl() 
     // 缓存url恢复为默认的首页
      saveBeforeLoginUrl('/')
      // 此处或背景图可以插播一段广告 ~~~
      setTimeout(() => {
        this.$router.push({path: url})
      }, 1000)
    }
  }
</script>

后端处理

  • 微信授权服务器回调后端的callback接口,携带参数code
  • 后端callback接口获取code后,请求以下链接获取网页授权access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code, 接口返回值:
{
  "access_token":"ACCESS_TOKEN",
  "expires_in":7200,
  "refresh_token":"REFRESH_TOKEN",
  "openid":"OPENID",
  "scope":"SCOPE"
}
  • 通过openid查询/写入数据库,得到数据库user信息。
  • 使用JWT规则生成token,重定向到前端的auth页面。

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容