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 相关文章推荐
TextArea 控件的最大长度问题(js json)
Dec 16 Javascript
jQuery UI-Draggable 参数集合
Jan 10 Javascript
解析offsetHeight,clientHeight,scrollHeight之间的区别
Nov 20 Javascript
在Javascript中处理数组之toSource()方法的使用
Jun 09 Javascript
Zero Clipboard实现浏览器复制到剪贴板的方法(多个复制按钮)
Mar 24 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 Javascript
原生js实现中奖信息无间隙滚动效果
Jan 18 Javascript
Vue项目webpack打包部署到服务器的实例详解
Jul 17 Javascript
详解适配器在JavaScript中的体现
Sep 28 Javascript
js实现简单进度条效果
Mar 25 Javascript
vue webpack build资源相对路径的问题及解决方法
Jun 04 Javascript
vue 解决provide和inject响应的问题
Nov 12 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中限制ip段访问、禁止ip提交表单的代码分享
2014/08/22 PHP
Symfony页面的基本创建实例详解
2015/01/26 PHP
php5与php7的区别点总结
2019/10/11 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
js 替换功能函数,用正则表达式解决,js的全部替换
2010/12/08 Javascript
通过onmouseover选项卡实现img图片的变化
2014/02/12 Javascript
jQuery元素的隐藏与显示实例
2015/01/20 Javascript
jquery获取多个checkbox的值异步提交给php
2015/07/07 Javascript
Jquery 1.9.1源码分析系列(十二)之筛选操作
2015/12/02 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
基于javascript实现根据身份证号码识别性别和年龄
2016/01/22 Javascript
jQuery实现简易的输入框字数计数功能示例
2017/01/16 Javascript
关于foreach循环中遇到的问题小结
2017/05/08 Javascript
初探JavaScript 面向对象(推荐)
2017/09/03 Javascript
给vue项目添加ESLint的详细步骤
2017/09/29 Javascript
Vue中之nextTick函数源码分析详解
2017/10/17 Javascript
vue scroller返回页面记住滚动位置的实例代码
2018/01/29 Javascript
js实现星星打分效果
2020/07/05 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
[52:44]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第一场 6.3
2018/06/04 DOTA
Python使用urllib2获取网络资源实例讲解
2013/12/02 Python
python中os操作文件及文件路径实例汇总
2015/01/15 Python
Python操作Sonqube API获取检测结果并打印过程解析
2019/11/27 Python
Canvas环形饼图与手势控制的实现代码
2019/11/08 HTML / CSS
抽象类和接口的区别
2012/09/19 面试题
AssertionError 跟一下那个类是 “is – a”的关系
2012/02/21 面试题
信息专业本科生个人的自我评价
2013/10/28 职场文书
新闻专业应届生求职信
2013/10/31 职场文书
《最大的麦穗》教学反思
2014/04/17 职场文书
小学阳光体育活动总结
2014/07/05 职场文书
学雷锋的心得体会
2014/09/04 职场文书
护士工作失误检讨书
2014/09/14 职场文书
行政执法队伍作风整顿个人剖析材料
2014/10/11 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书
python设置 matplotlib 正确显示中文的四种方式
2021/05/10 Python
pytorch中Schedule与warmup_steps的用法说明
2021/05/24 Python