Vue微信项目按需受权登陆策略实践

写在前面

项目采用Vue做为开发框架,用户浏览页面时有两种状况:前端

  1. 一种是须要用户先登陆以后才能继续浏览;
  2. 另外一种是用户无需登陆便可随意浏览。

在无需用户登陆的页面中,可能包含须要用户信息的操做,此时就须要用户登陆以后方能进行后续操做。所以,须要对受权登陆策略进行区分。后端

思路

通常而言,咱们为微信开发的H5页面,进入页面的时候就进行鉴权,要求用户登陆以后才能继续浏览。但因为产品需求,这个项目咱们须要对不一样页面的鉴权策略进行划分,按照通常与特殊进行设计:promise

  1. 通常状况,用户进入页面第一时间要求用户受权登陆,按照常规的微信受权登陆流程,登陆以后,用户继续浏览。
  2. 特殊状况,为无需用户登陆的页面配置白名单,只要进入存在于白名单的路由,不进入检测用户登陆状态的函数,直接渲染页面。
  3. 对于用户未登陆状态下进行的须要用户信息的操做,按照我目前的理解,即便是基于微信的静默受权,页面也必须从新刷新,没法作到真正无感受权而且继续用户的操做。所以我选择在前端层面给用户更友好的提示,让用户了解受权过程,缺点是前一次操做仅仅是触发受权登录,受权登陆后,用户须要再次进行操做。
// routerRule.js

export default function routerRule (router, whiteList = []) {
    // other codes...
    
    router.beforeEach( (to, from, next ) => {
        // 由于受权登陆涉及异步操做,所以使用promise,成功的回调中调用next函数
        new Promise((resolve, rejects) => {
            
            if ( whiteListRouter.indexOf(to.path) !== -1 ) {
                resolve()
                return
              }
            
            // 常规页面受权登陆过程
            if (hasToken()) {
                // codes,获取用户信息而且跳转所需跳转的页面
                
            } else {
                // 判断用户是否已经进行微信受权
                if (hasAuthed()) {
                    // 进行过微信受权以后,重定向回来的url中包含了微信的受权信息,能够将url上截取的参数发送到服务器,换取用户的token,随后进入上述有token时候的步骤
                    getWechatUserInfo().then(res => {
                        resolve()
                    })
                    
                } else {
                    // 用户还没有进行微信受权,则调用微信受权的方法,进行受权登陆。
                    getWechatAuth()
                }
            }
            
        }).then( res => {
            next()
        })
    })
    
    
    router.afterEach(( to, from ) => {
        wxShare({ title: to.meta.title, desc: to.meta.shareDesc, link: to.meta.shareLink, logo: to.meta.shareLogo})
      })
  
}


复制代码

本项目是在用户初次进行微信绑定时,就将用户的微信信息与本站的用户信息进行的绑定,所以在获取用户微信受权信息后,就能够获取到用户的token,从而获取用户在本站的其余用户信息。服务器

在无需登陆页面的进行须要权限的操做的处理

根据上面的逻辑,进入白名单以后,整个函数已经被return掉,不会进入下面的鉴权过程。可是若是是在此种页面上进行须要权限的操做,那么就须要触发受权登陆流程,而且在受权以后,要一并获取用户信息。微信

// checkLogin.js

export function checkLogin({ redirectUrl, wxAuthLoading, wxAuthLoaded, callback } = {}) {
    if (getToken()) {
        // ...
        callback && callback()
    } else {
        // 提示用户正在受权中
        wxAuthLoading && wxAuthLoading()
        getWechatAuth( redirectUrl || window.location.href ).then( res => {
            // 受权完毕,提示用户受权成功
            wxAuthLoaded && wxAuthLoaded()
        })
    }
}

复制代码

同时,咱们须要对路由白名单添加一些操做微信开发

// routerRule.js

export default function routerRule (router, whiteList = []) {
    // other codes...
    
    router.beforeEach( (to, from, next ) => {
        // 由于受权登陆涉及异步操做,所以使用promise,成功的回调中调用next函数
        new Promise((resolve, rejects) => {
            
            if ( whiteListRouter.indexOf(to.path) !== -1 ) {
                // 若是已经进行微信受权可是没有token值的,就调用如下函数获取token值
                if ( !hasToken() && hasAuthed() ) {
                    getWechatUserInfo().then(res => {
                        resolve()
                    })
                }
                resolve()
                return
              }
            
            // 常规页面受权登陆过程
            if (hasToken()) {
                // codes,获取用户信息而且跳转所需跳转的页面
                
            } else {
                // 判断用户是否已经进行微信受权
                if (hasAuthed()) {
                    // 进行过微信受权以后,重定向回来的url中包含了微信的受权信息,能够将url上截取的参数发送到服务器,换取用户的token,随后进入上述有token时候的步骤
                    getWechatUserInfo().then(res => {
                        resolve()
                    })
                    
                } else {
                    // 用户还没有进行微信受权,则调用微信受权的方法,进行受权登陆。
                    getWechatAuth()
                }
            }
            
        }).then( res => {
            next()
        })
    })
    
    
    // other codes...
  
}


复制代码

坑点以及不完善的地方

  1. 这个方案在用户受权以后,在路由跳转以前,必定要先获取用户信息,不然在url上的微信受权信息就会丢失,获取用户信息就会失败。
  2. 这个方案的缺点在于,须要开发者对在免登录页面的全部需权限操做都加上checkLogin判断。因为这种需权限的操做通常都是发送异步请求,因此若是不考虑减小没必要要的异步请求的状况下,能够统一在请求的方法上设置拦截器,判断后端返回的code,若是返回的是用户未登陆的code,就进行微信受权。这种作法开发过程比较方便,可是会在用户未登陆状况下发送了一些没必要要的请求给后端,感受不太好。

这是本人开发过程当中想到的不成熟的方案,若是有更好的方法,请不吝告知,谢谢!框架

相关文章
相关标签/搜索