背景

前后端分离项目 — SpringSocial 绑定与解绑社交账号如微信、QQ
2018-08-14更新
时隔四个月第一次更新,因为项目重构有一次接触到了微信授权,思路已经比原来清晰的多了,将重新修改一下整个文章

场景

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

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

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

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();
});

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


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我在从本地拿参数解析,这个方法应该也是可行的,下次尝试后更新

原文地址:https://segmentfault.com/a/1190000014255151

vue 微信授权解决方案的更多相关文章

  1. VUE开发SPA之微信授权登录

    SPA单页应用中微信授权登录的一点思路 单页应用应该如何解决微信授权登录的尴尬跳转?后退无法返回?主要遇到的问题就是 先进入单页应用,一边渲染页面一边判断用户有没有登录,当判断到没有登录时异步数据请求 ...

  2. Vue/小程序/小程序云+Node+Mongo开发微信授权、支付和分享

    大家好,我是河畔一角,今天给大家介绍我的第三门实战课程:基于微信开发的H5.小程序和小程序云的授权.支付和分享专项课程. 一.这一次为什么会选择微信支付和分享的课题呢? 金庸的小说中曾提到:有人的地方 ...

  3. 关于vue跨域名对接微信授权认证和APP授权认证

    这种情况一般也只会出现在前后端分离,跨域名授权的时候吧.耗费了一个前端+一个后台+一个网关,熬夜通宵了两天才整出来一套方法(你们见过凌晨6点的杭州吗,对,我下班的时候天黑了,到家天亮了....),和开 ...

  4. 解决 VUE 微信登录验证 【感谢原文:https://segmentfault.com/a/1190000009493199】

    [感谢原文:https://segmentfault.com/a/1190000009493199] SPA单页应用中微信授权登录的一点思路 单页应用应该如何解决微信授权登录的尴尬跳转?后退无法返回? ...

  5. Vue微信自定义分享时安卓系统config:ok,ios系统config:invalid signature签名错误,或者安卓和ios二次分享时均config:ok但是分享无效的解决办法

    简述需求:要求指定页面可以进行微信自定义分享(自定义标题,描述,图片,链接),剩下的页面隐藏所有基础接口.二次分享依然可以正常使用,切换至其他页面也可以正常进行自定义分享. 这两天在做微信自定义分享的 ...

  6. 解决微信授权回调页面域名只能设置一个的问题 [php]

    最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读. 在做项目集成微信登录以及微信支付的时候,都需要进行用户授权.这 ...

  7. url带#号,微信授权,微信分享那些坑

    微信授权的方法是,在项目里面配置拦截器(此处可以参考各个框架的拦截器)没有拦截器也可以,反正意思就是跳转到项目里的时候判断微信环境 如果是微信环境, 判断微信环境的方法是 var ua = windo ...

  8. VUE 微信开发

    1.工具 1.电脑版微信客户端window版本(1.x.x 亲测可以在谷歌浏览器进行微信授权登录,版本越来越好)或者用微信开发工具.很久之前就是用这个方法搞定用chrome进行微信登录授权. 2.us ...

  9. SPA单页应用前后分离微信授权

    项目基于微信公众号开发,业务完全依赖微信授权,也就是用户进入页面已经完成授权获取到用户的OpenId. 需要有一个授权中间页:author.vue 基本实现思路: 无论使用哪个url进入页面都会先触发 ...

随机推荐

  1. P5058 [ZJOI2004]嗅探器 tarjan割点

    这个题是tarjan裸题.最后bfs暴力找联通块就行.(一开始完全写错了竟然得了70分,题意都理解反了...这数据强度...) 题干: 题目描述 某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络 ...

  2. min-max容斥小结

    https://www.zybuluo.com/ysner/note/1248287 定义 对于一个集合\(S\), \(\min(S)\)表示其第一个出现的元素(\(or\)最小的元素), \(\m ...

  3. linux 条件测试 ******

    文件状态测试 -b filename 当filename 存在并且是块文件时返回真(返回0) -c filename 当filename 存在并且是字符文件时返回真 -d pathname 当path ...

  4. Access restriction:The type JPEGCodec is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\rt.jar 报错

    报错: Access restriction:The type JPEGCodec is not accessible due to restriction on required library C ...

  5. 70.资金管理-福利表管理 Extjs 页面

    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8&quo ...

  6. vs2010打开vs2012项目

    修改.sln文件的前两行 修改前: Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 修 ...

  7. Kubernetes 集群中使用 Helm 搭建 Spinnaker

    在我们部署Spinnaker之前,我们需要一个YAML格式的配置文件,它会包含了一些配置信息.可以从Spinnaker Helm Chart repository[2]获得这个文件. $curl -L ...

  8. roundabout旋转幻灯

    jquery.roundabout.js文件/** * jQuery Roundabout - v2.4.2 * http://fredhq.com/projects/roundabout * * M ...

  9. Elasticsearch索引的操作,利用kibana(如何创建/删除一个es的索引?)

    我们已经通过索引一篇文档创建了一个新的索引 .这个索引采用的是默认的配置,新的字段通过动态映射的方式被添加到类型映射.现在我们需要对这个建立索引的过程做更多的控制:我们想要确保这个索引有数量适中的主分 ...

  10. ansible剧本

    yaml简介 YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写,早先YAML的意思其实是:"Yet Anoth ...