vue 微信受权解决方案

背景

vue先后端分离开发微信受权
2018-08-14更新
时隔四个月第一次更新,由于项目重构有一次接触到了微信受权,思路已经比原来清晰的多了,将从新修改一下整个文章php

场景

app将商品分享到微信朋友圈或者分享给微信好友,用户点击页面时进行微信受权登录,获取用户信息。
问题:没有固定的h5应用首页,回调不能到index。受权后重定向url带参数而且很长css

本人愚钝,开发过程当中,尝试过不少方法,踩坑不足以形容个人心情,能够说每一次都是一次跳井的体验啊。前端

1.一开始尝试的方式是前端请求微信链接,返回code,而后code做为再去请求后台接口获取token,后面看到别人的博客说这个方法很差,最好就是直接请求后台接口,而后后台返回url作跳转,因此就采用了最传统的方法,后台返回url,前台跳转。vue

2.这个时候就出现一个问题,微信受权要跳跳跳,最终想回到第一次点进来时候的连接就蛋疼了,从网上查了一下解决方法,将连接自己做为redirect_uri参数,大概就是这个样子java

https://open.weixin.qq.com/connect/oauth2/authorizeappid=xxxxxxxxxxxxxxxxxx&redirect_uri=*www.admin?http://www.xxx.com/h5/product*&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect

然而咱们的前台连接是这个鬼样子的,自己带参数,并且超长,what?微信可能不会接受我长这么丑。/(ㄒoㄒ)/~~vuex

http://www.xxx.com/h5/product?id=6RedfM5O4xeyl0AmOwmyipkHr8AQCv-hYXZVAIFTwDXOsWSKqgu3VaCmaKSerBnacvWuzO3Zwdf8y%2F2K2lvqkluV6Ane4LCAKyPU2tPAPj%2FMF6F6xkzp27GqqpNya7HbdEA34qGQJvHIA9tlIMkeEWid1112b8oZuP3FQBwU%2F%2FMaSrovzQP6LlzWamyPnv0vMizu8uh0ItpJOQUV1m%2FtemF3U9KuHo8rXCw%3D

最终放弃了这个方案后端

3.考虑如何重定向个人前台地址,而且获取tokenapi

接下来就是我如今用的方法,bug还有不少,先分享一下个人方法,后期优化或有更好的方法再作修改
在main.js中路由全局钩子判断本地是否是有user_token,也就是微信受权后返回的token,若是没有token,而且当前的路由不是author(专门为了受权而生的页面),那就保存当前的url,好比www.xxx.com/h5/product?id=6RedfM5O4xeyl0AmOwm,而后进入author。那若是本地有token,就是用户以前受权拿到过token而且vuex里没有用户信息,那我就获取用户信息并保存在vuex中,这里遇到一个问题就是token会出现过时的状况,那我就删除了本地的user_token,window.localStorage.removeItem("user_token");刷新页面 router.go(0);这个时候就从新走了一遍若是没有token的状况。
初版方法微信

router.beforeEach((to, from, next) => {
      //   第一次进入项目
      let token = window.localStorage.getItem("user_token");
      
      if (!token && to.path != "/author") {
        window.localStorage.setItem("beforeLoginUrl", to.fullPath); // 保存用户进入的url
        next("/author");
        return false;
      } else if (token && !store.getters.userInfo) {
      //获取用户信息接口
        store
          .dispatch("GetUserInfo", {
            user_token: token
          })
          .catch(err => {
            window.localStorage.removeItem("user_token");
            router.go(0);
            return false;
          });
      }
      next();
    });

2018-08-14第二版方法
不一样的地方是将跳转判断从author.vue里拿出来放这里了逻辑其实很简单,有token获取信息,没token跳转受权app

router.beforeEach((to, from, next) => {
  
  const token = window.localStorage.getItem('user_token')
  if (token) {
    if (to.path === '/author') {
      next({
        path: '/'
      })
    } else {
      store
        .dispatch('GetUserInfo', {
          user_token: token
        })
        .then(res => {
          // 拉取用户信息
          next()
        })
    }
  } else {
    if (to.path !== '/author') {
      // 保存用户进入的url
      if (to.path === '/shop' || to.path === '/product') {
        window.localStorage.setItem('authUrl', to.fullPath) // 保存用户进入的url
      }
      store.dispatch('GetAuthUrl').then(res => {
        // 此处返回的是后台拼接的微信受权地址,前台也是能够拼接的,跳转到微信受权
        window.location.href = res.data.url //https://open.weixin.qq.com/connect/oauth2/authorize?appid=aaaaa&redirect_uri=后端java或php地址&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect
      })
    } else {
      next()
    }
  }
})

下面就是进入author.vue的逻辑,第一次进入author, www.xxxx.com/h5/author,判断连接有没有token参数,若是没有就跳微信受权,而后后台会重定向回来并携带token,如: www.xxxx.com/h5/author?token=xxxxxxxxx&msg=200

初版

<template>
   <div>
受权中。。。
   </div>
</template>

<script>
  
   import {
      getWxAuth
   } from '@/service/getData'
   import {
      GetQueryString 
   } from '@/utils/mixin';
   export default {
      data() {
         return {
            token: '',
         };
      },
      computed: {
       
      },
      created() {
         this.token =  window.localStorage.getItem("user_token");
         //判断当前的url有没有token参数,若是不存在那就跳转到微信受权的url
         //就是前面说的ReturnGetCodeUrl方法
  
         if (!GetQueryString("token")) {
            this.ReturnGetCodeUrl();
         } else {
           //若是有token,如http://www.xxxx.com/h5/author?token=xxxxxxxxx&msg=200,这里的参数就是后台重定向到前台http://www.xxxx.com/h5/author,并携带的参数。这样就能够拿到咱们想要的token了
           //判断一下后台返回的状态码msg,由于可能出现微信拿不到token的状况
            let msg = GetQueryString("msg")
            if (msg = 200) {
               this.token = GetQueryString("token");
               //存储token到本地
                window.localStorage.setItem("user_token", this.token);
                //获取beforeLoginUrl,咱们的前端页面
               let url =  window.localStorage.getItem("beforeLoginUrl");
               //跳转
               this.$router.push(url);
               //删除本地beforeLoginUrl
               removeLocalStorage("beforeLoginUrl");
            }else{
            //msg不是200的状况,可能跳到404的错误页面
            }
         }
      },
      methods: {
       
         async ReturnGetCodeUrl() {
            let {
               data
            } = await getWxAuth({});
            if (data.status == 200) {
              
               window.location.href = data.url;
            }
         },

         
      },
      watch: {},

      components: {},


      mounted: function () {}
   }
</script>
<style lang='scss' scoped>

</style>

GetQueryString方法

mixin.js

export const GetQueryString = name => {
  var url = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  var newUrl = window.location.search.substr(1).match(url);
  if (newUrl != null) {
    return unescape(newUrl[2]);
  } else {
    return false;
  }
};

第二版
只用来后台拿到参数返回到author页面后的携带的参数若是获取成功则跳转到受权以前保存的url若是失败提示用户关闭网页从新受权,另外有一点值得注意,微信名里有特殊字符的须要转码要不受权会失败

<!-- author -->
<template>
  <div>
    受权中。。。
  </div>
</template>

<script>
  import {
    mapGetters
  } from 'vuex'
  import {
    Toast
  } from 'mint-ui'
  import {
    GetQueryString,
    setLocalStorage,
    getLocalStorage,
    removeLocalStorage
  } from '@/utils'
  export default {
    data() {
      return {
        token: ''
      }
    },
    computed: {
      ...mapGetters([
        'userInfo'
      ])
    },
    created() {
      const wxtoken = GetQueryString('token')
      const code = GetQueryString('msg')
      if (wxtoken && Number(code) === 200) {
        setLocalStorage('user_token', wxtoken)
        const historyUrl = getLocalStorage('authUrl')
        this.$router.replace(historyUrl)
        //  removeLocalStorage('authUrl')
      } else {
        // 没有拿到后台访问微信返回的token
        Toast('受权失败请关闭网页从新进入')
        removeLocalStorage('share_token')
        removeLocalStorage('authUrl')
      }
    }
  }

</script>
<style lang='scss' scoped>


</style>

整个过程是能够实现受权,可是以为代码写得很差,之后的开发中但愿可以有更优的方法。但愿能和你们交流学习。2018-08-14更新,总结一下,第二次开发流程作了简化,可是整个思路仍是同样,我以前想到过另一种方法,是将个人那串长参数先保存在本地,而后去受权的时候就可让后台帮我跳转到固定页面如/product我在从本地拿参数解析,这个方法应该也是可行的,下次尝试后更新

相关文章
相关标签/搜索