场景
在微信中打开需要授权的web应用时,通常得通过跳转微信授权地址:
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=xxxx
&redirect_uri=www.myapp.com
&response_type=code
&scope=snsapi_base
&state=xxxx
#wechat_redirect
在成功授权后夹带着authCode及 state
值自动返回到 redirect_uri
参数所指定的地址,再拿 authCode 在开发者后端的登录接口中完成登录,最后手动跳转到目标页面(这个特定页可以在授权前先记录下来,最后再拿出来做跳转),一切都非常自然。
问题
然而会有这样的需求:用户通过手机实体按键或全屏滑动操作返回,最终必定会到达处理授权登录的页面,从而再次触发登录,并再次跳转回来,无法退出应用。
方案
在后端登录接口调取成功后、跳转到目标页面前,通过 window.history.replaceState()
方法手动添加一个 history,比如:
window.history.replaceState(null, null, window.location.protocol + '//' + window.location.host + '/#/wechat_exit');
replaceState()
并不会直接跳转到 /wechat_exit
,但是在下次用户做出返回操作时会经过!这是与使用 pushState()
存在的本质区别,因为 replaceState()
清除了之前的 history,这也就使得用户无法通过物理操作手动返回到跳转前的页面(授权登录页)。
接下来全局观察并捕获这个 history,当到达 /wechat_exit
时主动调取 微信接口 closeWindow()
来关闭应用窗体。以vue为例添加路由拦截来全局观察:
router.beforeEach((to, from, next) => {
if (to.path === '/wechat_exit') {
common.getWechatSDK(wx => {
wx.closeWindow();
});
}
}
common.getWechatSDK()
是已封装微信 js sdk 接口的方法,在获取成功后调取 closeWindow()
接口,更多js接口请参照:https://work.weixin.qq.com/api/doc#90001/90144/90540
https://www.weixinsxy.com/jssdk/