关于企业微信中开发第三方应用遇到的退出问题

1,371 阅读4分钟

前言

这是在公司实际开发中遇到的一个问题,虽然不是大问题,但确实是很影响用户体验,这里就记录一下遇到该问题的解决方案与处理,

在用户进入到我们的应用时通过一系列的授权最终进入到我们的首页,此时如果用户点击左上角的返回按钮或者手机返回,应该是返回到企业微信的应用列表,但实际上用户按返回键之后还是会返回到首页,从首页进入到了首页,这很奇怪,也就是用户实际上退出应用需要按两次。

欢迎访问个人博客:chihiross.com

问题分析

当我们在企业微信中开发应用是需要使用到微信提供的授权登录的,这里就简单描述一下,注意只讲前端部分,至于整个流程请查看官网文档,我们前端要做的事情是在用户进入到应用中之后首先判断是否有 token,如果不存在的时候就需要跳转到我们构造的一个企业微信的授权链接,如图:

企业微信文档:developer.work.weixin.qq.com/document/pa…

image-20220902205356562

我这里是通过window.location.replace来跳转的,也应该使用这个api跳转,因为这样的话历史栈中就会把一开始进入到我们项目的历史替换掉

window.location.replace(wxoauth2)

那么当我们进行 replace 之后就会跳转到企业微信授权页,我们构造链接时会在url上加上redirect_uri=xxx,这就是指名了当进入到企业微信授权页中授权完成之后会重定向到我们指定的这个地址,好!,看着流程非常的没有问题,接着往下看,当重定向回来之后企业微信会在重定向的地址中在加上我们后端需要的参数,这里就不多说了,反正当企业微信重定向到我们的页面之后,我这里指定的是登录页,那么也就是进入登录页面之后我们进行判断参数然后去请求我们自己的后台并携带参数

const router = useRouter()
const code = router.currentRoute.value.query.code
const state = router.currentRoute.value.query.state
const redirectUrl = decodeURIComponent(Base64.decode(state))
const isSuccess = ref(true)
if (code) {
  // 这里是在 vuex 中进行的请求
  store.dispatch('QwWebLogin', { appid: appid(), code, state }).then(res => {
    if (state) {
      router.replace(redirectUrl)
    } else {
      router.replace('/')
    }
  }).catch(err => {
    // 登录失败,提示
    window.DVM.Notify({ type: 'danger', message: `登陆失败,请重试` })
    isSuccess.value = false
  })
} else {
  window.DVM.Notify({ type: 'danger', message: `登陆失败,请重试` })
  isSuccess.value = false
}

那么登录完成之后就又会从我们项目的登录页面重定向到首页,进入应用 -> 微信授权链接 -> 应用登录 -> 应用首页,我们这里全都是使用的 replace,按理来讲在我们的历史栈中应该一个,但实际当我打开的时候发现有两个,????

经过查询各种文章之后发现好像是在微信内置浏览器中location.replace好像是不生效的,也就是还是会保留一个历史,那就说得清楚了,也就是第一次退出应用的时候退出到了这个微信授权之后又重定向到了我们的应用,此时已经在localStorage时存储了token

授权.drawio

解决方案

这个解决方案不是最优解,我认为只是解决方案中的一种,如果有任何异议可在评论区中讨论

既然在微信中location.replace不生效,我们只能想另外的办法也是想了比较久,有在守卫中判断是否是第二次进入的然后执行window.close方法等,但是都有缺陷,只有一种比较的符合情况并且测试起来咩有什么问题,那就是我们在登录页面中做处理,请看代码

store.dispatch('QwWebLogin', { appid: appid(), code, state }).then(res => {
   history.length === 2 ? history.back() : router.replace(redirectUrl)
})

为什么要这么写的原因:

  • 只有首次进入的时候才会进入到授权页面,不会影响其他页面或功能
  • 只有进入到授权页面的时候因为保留了两个历史栈所以可以拿到histroy.lenght === 2

那么目前来看在这里做是最合适的,history.back(),会帮助我们后退一个历史栈,也就退到了最开始进入的/页面,此时已经有了token,那么会重定向到首页,那么原来写的是router.replace(redirectUrl),这个方法是vue router提供的方法,帮助我们进入某个页面并替换原来的那个历史,所以history.back()是最合适的。

授权2

最后

由于写博客比较少,想培养一个写博客的习惯,写的不好勿喷请指点,或者有疑问在评论区交流私信都可以,最后宣传一下自己的博客( ^__^ )

个人博客:chihiross.com