背景
最近在开发公众号微信h5模块,在公众号底部配置菜单链接,点击链接跳转到不同的模块,实现功能模块化。
可能存在的入口
公众号底部菜单
微信卡片分享菜单
未关注公众号从公众号服务入口进入
公众号H5登录流程
配置的菜单链接大概是这样wechat_redirect_url的前半段是服务端的接口,用于服务端去获取微信官方的code。拿到这个code之后后端会把code带到uri的参数上面返回给我们调用服务端的一个登录接口。
服务端会拿到code去获取微信的access_token。然后再用access_token去获取openid以及同意微信授权后可以获得unionid。
uri中的链接就是我们需要跳转的业务页面。最后scope是必传参数,有snsapi_base和snsapi_userinfo两类
scope=snsapi_base和scope=snsapi_userinfo授权方式的不同
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。
踩坑
问题1
之前boss要求的是不准进入页面后让用户点击使用完整服务,我配置的菜单链接就是scope=snsapi_base的链接,结果导致我们只能够获取到用户的openid,拿不到用户的完整信息后面服务做了调整,导致scope=snsapi_base在未授权的情况下,取不到openid和unionid,这下完了,新用户进来只报错,连注册成功都做不到了
解决方案
判断用户是否存在token,如果存在token就默认是登录状态,如果不存在,就弹出提示弹窗,告诉用户您需要授权才能体验完整服务。用户点确定就重定向到scope=snsapi_userinfo的链接上,如果用户真的未授权微信会弹出授权弹窗给用户授权,如果已经授权就会跳到uri的相应服务页面
mounted(){
if (!localStorage.getItem("token")) {
Dialog.confirm({
title: "",
message: "为确保您的隐私安全和最佳使用体验,我们需要您的授权",
confirmButtonText: "同意",
cancelButtonText: "拒绝",
confirmButtonColor: "#3888FE",
})
.then(() => {
window.location.href =`${window.location.origin}/xxx/xxx/wechat_redirect_url?uri=${window.location.origin}/xxx/index.html&scope=snsapi_userinfo`
})
}
}
问题二
因为上一个坑没填完,也因为我们服务端一些原因,导致我在token过期之后没有清理到token数据,于是进入页面之后发现token还在,所以一直报错401,且token没被清理掉。所以就呈现了无法使用的尴尬局面
解决方案
和后端及时对接401情况的代码排查,在接口报401或者是msg报带有401的串的时候清除用户的token,并在app.vue的created生命周期中加上路由页面跳转的方法router.beforEach(to,form,next)拦截路由,如果路由跳转的时候不存在token的话,也提醒用户去授权登录
created () {
// 在created钩子函数中使用router.beforeEach
this.$router.beforeEach((to, from, next) => {
if (!localStorage.getItem("token")) {
Dialog.confirm({
title: "",
message: "为确保您的隐私安全和最佳使用体验,我们需要您的授权",
confirmButtonText: "同意",
cancelButtonText: "拒绝",
confirmButtonColor: "#3888FE",
})
.then(() => {
window.location.href =`${window.location.origin}/xxx/xxx/wechat_redirect_url?uri=${window.location.origin}/xxx/index.html&scope=snsapi_userinfo`
})
} else {
next()
}
});
}
关于静默授权
1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。