vue hash模式下微信受权登陆

背景

vue-cli项目。路由是hash模式。须要受权的场景有:项目入口处(App.vue),指定页面(建立时、methods 方法内);能够携带参数vue

思路

因为hash模式# 号的存在,受权后连接会被扰乱。因此 我但愿在 受权前 将重定向的连接 即 redirect_uri 改成没有# 的url。而后在 项目入口处 进行 url 重置,将其改回到 丑陋的 带#连接。vue-cli

即:两步操做api

一、受权前 将redirect_uri 改成没有# 的url微信

二、项目入口处,将没有#的url改回到 带#的url,跳到指定页面。app

主要代码

一、受权前,redirect_uri 重置

这里会将当前页面的原有参数信息、额外参数、codepath参数 做为 redirect_uri 的新参数。其中codepath是 用来指定 跳转页面的,一般为 受权发起页。url

/**
   * 开始设置页面连接,进行code 受权重定向
   *
   * @param scope 受权做用域
   * @param path  受权所在页面 path
   * @param extraPm 额外参数,须要在 配置中 进行参数配置
   * @returns {string}
   */
  get_codeV3(scope, path, extraPm={}) {
        if (process.env.NODE_ENV === 'development' && config.isMockWeChat)
          return '0713eFVW0AmFP12kGVTW0oGDVW03eFV2'

      let homeUrl = '', searchOb = {}, searchstr = ''
      let oriUrls = window.location.href.split('?')
      let baseShareURl = window.location.origin + window.location.pathname
      homeUrl = baseShareURl
      if (oriUrls.length > 1) {
        let searchUrls = oriUrls[1].split('#')
        let searchUrlReal = searchUrls[0]
        searchOb = qs.parse(searchUrlReal)
        let {code} = searchOb
        if (code)
          delete searchOb.code
      }
      searchOb.codepath = path
      Object.assign(searchOb, extraPm)
      searchstr = `?${qs.stringify(searchOb)}`
      homeUrl += searchstr

      let redirect_uri = encodeURIComponent(homeUrl);

      let response_type = 'code';
      // 应用受权做用域,
      // snsapi_base (不弹出受权页面,直接跳转,只能获取用户openid),
      // snsapi_userinfo (弹出受权页面,可经过openid拿到昵称、性别、所在地。而且, 即便在未关注的状况下,只要用户受权,也能获取其信息 )

      // 重定向后会带上state参数,开发者能够填写a-zA-Z0-9的参数值,最多128字节
      let state = '';
      let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`;
      window.location.href = url;
    }

二、连接前置判断

在项目入口处,发现有 codepath 参数,即 将该连接视为 受权后的redirect_uri 连接。进行页面重定向,跳转到 codepath 指定页面spa

/**
   * 页面重定向(受权)-确保页面连接正常
   * 支持多参、无参、指定页面
  * code 在 返回的search 里 * @returns {{needRedirect: boolean, homeUrl: string, search: {}}}
*/ urlResetForWxCode: function () { //须要重定向时:codepath 参数 与 code 参数同在。 let needRedirect = false, homeUrl = '', searchOb = {}, searchstr = '' let oriUrls = window.location.href.split('?') let baseShareURl = window.location.origin + window.location.pathname homeUrl = baseShareURl if (oriUrls.length > 1) { let searchUrls = oriUrls[1].split('#') let searchUrlReal = searchUrls[0] let searchObReal = {} searchOb = qs.parse(searchUrlReal) let { codepath } = searchOb needRedirect = codepath if (codepath) { config.platform.wxCode[codepath].forEach(item => searchObReal[item] = searchOb[item]) if (config.platform.wxCode[codepath].length) searchstr = `?${qs.stringify(searchObReal)}` homeUrl += `#${codepath}` + (searchstr.length > 1 ? searchstr : '') } } return { needRedirect, homeUrl, search: searchOb } }

// 配置信息localstorage

config = {
  platform: {
    wxCode: {'/': ['hello', 'yiha'], '/spe': ['spp']}, // 微信受权-须要受权的页面: [页面用到的参数]
  }

 

使用

一、受权发起位置一般有 项目入口处、页面create 时,页面 指定方法内。

if (!storage.getToken()) {// code 受权标志 保存在localstorage。
        wx_jssdk.get_codeV3('snsapi_userinfo', '/')
        return
      }

二、项目入口处进行前置判断

// App.vuecode

created(){

      // 能够在项目入口处 进行code受权
      if (!storage.getToken()) {// code 受权标志 保存在localstorage。
        wx_jssdk.get_codeV3('snsapi_userinfo', '/')
        return
      }
      // 项目只要用到受权,则须要进行重定向判断。
      let {needRedirect, homeUrl, search} = browserUtil.urlResetForWxCode()
      if (needRedirect) {
        storage.setToken({code: search.code}) // 保存code
        window.location.href = homeUrl
      }

    }

 

 写在最后

想着尽可能可以作到配置化、可扩展,目前很low。凑合用吧😄orm

配置化的体现:

连接前置判断方法内,组装连接参数时,我是只拿配置信息里的存在的参数。(方法里飘红的代码)。这是为了参数可控,避免没必要要的bug。

可扩展的体现:

在redirect_uri 重置方法 参数里,有一个额外参数,本来 想着只截取受权发起页的原始search参数就行了。但一想 会不会有这样的使用场景:

表单提交页,在提交时 才去发起受权。这样的话 可能受权后 原表单信息已丢失,即须要从新再来;体验并很差。那么可不能够 将表单数据做为 受权时的一部分参数,而后在受权成功后,页面从新create时 检测到有表单数据时 直接提交。(固然,你也能够经过local保存数据来实现这个功能,或者其余)

注:该额外参数 也须要在配置里注明,否则 前置判断里 会不予理会。

相关文章
相关标签/搜索