vue 微信授权登录解决方案


Posted in Javascript onApril 10, 2018

背景

vue前后端分离开发微信授权

场景

app将商品分享到微信朋友圈或者分享给微信好友,用户点击页面时进行微信授权登陆,获取用户信息。

问题:没有固定的h5应用首页。授权后重定向url带参数并且很长

本人愚钝,开发过程中,尝试过很多方法,踩坑不足以形容我的心情,可以说每一次都是一次跳井的体验啊。

1.一开始是前端请求微信连接,返回code,然后code作为再去请求后台接口获取token,后面看到别人的博客说这个方法不好,最好就是直接请求后台接口,然后后台返回url做跳转,所以就采用了最传统的方法,后台返回url,前台跳转。

async ReturnGetCodeUrl() {
  let {
    data
  } = await getWxAuth({});
  if (data.status == 200) {
    window.location.href = data.url;

    // 返回的结果
    // redirect_uri重定向的url是后台的地址,后台就是可拿到code,获取token
    // https://open.weixin.qq.com/connect/oauth2/authorizeappid=xxxxxxxxxxxxxxxxxx&redirect_uri=***url***&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect
    
  }
 },

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

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ㄒ)/~~

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

最终放弃了这个方案

3.考虑如何重定向我的前台地址,并且获取token

接下来就是我现在用的方法,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();
  });

下面就是进入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;
 }
};

整个过程是可以实现授权,但是觉得代码写得不好,以后的开发中希望能够有更优的方法。望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js Flash插入函数免激活代码
Mar 31 Javascript
JS 面向对象之神奇的prototype
Feb 26 Javascript
非常棒的10款jQuery 幻灯片插件
Jun 14 Javascript
JQuery中根据属性或属性值获得元素(6种情况获取方法)
Jan 17 Javascript
js 利用image对象实现图片的预加载提高访问速度
Mar 29 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
Jan 28 Javascript
js实现表单Radio切换效果的方法
Aug 17 Javascript
js判断空对象的实例(超简单)
Jul 26 Javascript
JS判断微信扫码的方法
Aug 07 Javascript
Vue动态获取width的方法
Aug 22 Javascript
解决vue 打包发布去#和页面空白的问题
Sep 04 Javascript
基于js Canvas实现二次贝塞尔曲线
Dec 25 Javascript
详解给Vue2路由导航钩子和axios拦截器做个封装
Apr 10 #Javascript
详解webpack 打包文件体积过大解决方案(code splitting)
Apr 10 #Javascript
Angular CLI在Angular项目中如何使用scss详解
Apr 10 #Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 #Javascript
bing Map 在vue项目中的使用详解
Apr 09 #Javascript
详解Vue打包优化之code spliting
Apr 09 #Javascript
node实现基于token的身份验证
Apr 09 #Javascript
You might like
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
2012/05/23 Javascript
Jquery实现搜索框提示功能示例代码
2013/08/13 Javascript
把jQuery的类、插件封装成seajs的模块的方法
2014/03/12 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
NodeJS中利用Promise来封装异步函数
2015/02/25 NodeJs
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
2016/08/15 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
基于jQuery实现的打字机效果
2017/01/16 Javascript
jquery插件canvaspercent.js实现百分比圆饼效果
2017/07/18 jQuery
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
2019/04/28 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
2019/09/03 jQuery
webpack HappyPack实战详解
2019/10/08 Javascript
mpvue实现微信小程序快递单号查询代码
2020/04/03 Javascript
Vue中watch、computed、updated三者的区别及用法
2020/07/27 Javascript
Node.js利用Express实现用户注册登陆功能(推荐)
2020/10/26 Javascript
vue实现点击出现操作弹出框的示例
2020/11/05 Javascript
在Python中使用mechanize模块模拟浏览器功能
2015/05/05 Python
浅析Python中的join()方法的使用
2015/05/19 Python
Python 的内置字符串方法小结
2016/03/15 Python
Django内容增加富文本功能的实例
2017/10/17 Python
python+splinter实现12306网站刷票并自动购票流程
2018/09/25 Python
python远程连接MySQL数据库
2019/04/19 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
使用Python的Turtle库绘制森林的实例
2019/12/18 Python
tensorflow实现读取模型中保存的值 tf.train.NewCheckpointReader
2020/02/10 Python
意大利奢侈品购物网站:Giglio
2018/01/05 全球购物
旷课检讨书大全
2014/01/21 职场文书
运动员口号
2014/06/09 职场文书
机关领导干部作风整顿整改措施
2014/09/19 职场文书
公司领导班子对照检查存在问题整改措施
2014/10/02 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
React配置子路由的实现
2021/06/03 Javascript