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 相关文章推荐
jQuery 对Select的操作备忘记录
Jul 04 Javascript
JS TextArea字符串长度限制代码集合
Oct 31 Javascript
jquery验证表单中的单选与多选实例
Aug 18 Javascript
自写的jQuery异步加载数据添加事件
May 15 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
Dec 13 Javascript
JS触摸与手势事件详解
May 09 Javascript
JQuery 封装 Ajax 常用方法(推荐)
May 21 jQuery
详解ES6语法之可迭代协议和迭代器协议
Jan 13 Javascript
iview在vue-cli3如何按需加载的方法
Oct 31 Javascript
js常用正则表达式集锦
May 17 Javascript
使用Vue.observable()进行状态管理的实例代码详解
May 26 Javascript
js实现无刷新监听URL的变化示例代码详解
Jun 03 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
PHP删除字符串中非字母数字字符方法总结
2019/01/20 PHP
推荐:极酷右键菜单
2006/11/29 Javascript
理解Javascript_14_函数形式参数与arguments
2010/10/20 Javascript
什么是DOM(Document Object Model)文档对象模型
2012/03/05 Javascript
js去除空格的12种实用方法
2013/11/08 Javascript
jquery $(&quot;#variable&quot;) 循环改变variable的值示例
2014/02/23 Javascript
JavaScript日期时间格式化函数分享
2014/05/05 Javascript
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
jQuery.Validate表单验证插件的使用示例详解
2017/01/04 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
JavaScript之iterable_动力节点Java学院整理
2017/06/29 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
浅谈Vue.js应用的四种AJAX请求数据模式
2017/08/30 Javascript
VsCode插件整理(小结)
2017/09/14 Javascript
Vue2.0设置全局样式(less/sass和css)
2017/11/18 Javascript
CSS3结合jQuery实现动画效果及回调函数的实例
2017/12/27 jQuery
使用vuex的state状态对象的5种方式
2018/04/19 Javascript
jQuery实现判断滚动条滚动到document底部的方法分析
2019/08/27 jQuery
jquery实现商品sku多属性选择功能(商品详情页)
2019/12/20 jQuery
利用scrapy将爬到的数据保存到mysql(防止重复)
2018/03/31 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
2018/06/14 Python
Python tcp传输代码实例解析
2020/03/18 Python
Python实现打包成库供别的模块调用
2020/07/13 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
2020/07/28 Python
html5的画布canvas——画出弧线、旋转的图形实例代码+效果图
2013/06/09 HTML / CSS
玩具公司的创业计划书
2013/12/31 职场文书
ktv好的活动方案
2014/08/15 职场文书
化验室岗位职责
2015/02/14 职场文书
初中英语教学反思范文
2016/02/15 职场文书
2019大学生社会实践报告汇总
2019/08/16 职场文书
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL