美文网首页程序员Web前端之路技术专栏
小程序:没了getUserInfo我们该何去何从?

小程序:没了getUserInfo我们该何去何从?

作者: 枸杞辣条 | 来源:发表于2018-05-19 03:15 被阅读344次

    最近,微信发布了小程序与小游戏获取用户信息接口调整。并在2018.5.10号正式实施,也就意味着用户登录接口不能使用wx.getUserInfo去获取一些敏感信息。

    PS:由于个人是用mpvue实现的,所以写法上会与原生有点奇怪,但这都不重要~

    后台需要哪些信息?

    小程序的一些后台配置我并不熟悉,就我司的开发流程大概需要:wx.logincodegetUserInfoivencryptedData。后台有了这些信息也就能够识别用户,拿到用户的一些信息,这就会让后台给前端一个token可以理解为session,因为小程序没有cookie,所以需要一个额外的token来标识用户,该token一般放置于与后台约定的报文头内。

    应该在哪些地方获得用户敏感信息?

    用户的一些敏感信息如encryptedData, iv等,并不应该在用户一进入小程序就获取它们,而是等到使用一些敏感接口的时候才去让用户授权。

    逻辑

    在废弃getUserInfo之后,最好的实践应该是在一些敏感接口,跳转至登录授权页面,只有用户点击授权页面的button之后才接口才会往下走。

    实现

    了解以上以后,可以按照axios的规则,封装自己的请求。这里假设已经封装好了。

    所以我们需要对fetch请求进行一层封装(注意:fetch不是原生,而是你自己封装好的)。接口的调用方法基本长这样:fetch.get('someApi', data, { ignoreToken })

    我们需要在请求之前做一层拦截器,每当发送请求时候没有设置ignoreToken时候就应该判断本地是否有token,如果有token那就一路畅通无阻。如果没有则调入获取token的逻辑。

    // 这里我们引用'minapp-api-promise'这个包,相当于把所有回调接口`promiseify`
    // 每一个请求都会走这个请求后再去执行真正的request
    import WXP from 'minapp-api-promise'
    const { getStorageSync } = WXP
    const requestInterceptor = (params) => {
      return new Promise(async (res, rej) => {
       let token = getStorageSync('token')
       // 如何有设置ignoreToken
       if (!params.ignoreToken) {
          if (!token) {
              // 调用自己写的getUserInfo,返回值为一个promise对象
              // 这里相当于一个开关闸,只有getUserInfo()的返回值resolve()之后
              // 该请求才会往下走,否则请求在这一直挂起
              await getUserInfo()
              token = getStorageSync('token')
          }
        }
        if (token) {
          req.header.auth = `${token}`
        }
        resolve(req)
      })
    }
    

    接下来是最重要的,如何写getUserIno

    let _getUserInfo = null
    export const getUserInfo = () => {
      if (_getUserInfo) {
          _getUserInfo = new Promise((res, rej) => {
            while(!getStorageSync(token)) {
              try {
                // 登录获得code
                const data = await WXP.login()
                // 该接口的用法在与如果你之前已经授权,
                // 那么调用该接口直接执行success,否则执行fail
                const user = await WXP.getUserInfo({ 
                  withCredentials: true,
                  lang: 'zh_CN',
                })
                // 判断用户是否授权过
                const set = await WXP.getSetting()
                // 发送一个忽视token的请求来获取token
                const res = await fetch.get(getTokenApi, {
                  iv: user.iv,
                  encryptedData: user.encryptedData,
                  code: data.code
                }, { ignoreToken: true })
                wx.setStorageSync('token', res.data.access_token)
                _getUserInfo = null
              } catch(e) {
                // 当用户未授权时
                wx.navigateTo({ url: login页面 })
                try{
                  await new Promise((resolve, reject) => {
                    // 如过你使用vuex可以直接放在store
                    // 没有的花你也可以放在原生的全局中
                    // 这样当跳转到用户授权页面时
                    // 不管用户授没授权,直接跳到最开始的循环。接下来自己脑补
                    wx.resolve = resolve; wx.reject = reject  
                  }) catch(e) {
                     continue
                  }
                }
              }
            }
          })
      }
      return _getUserInfo
    }
    

    以上最让人疑惑的估计就是_getUserInfo,我们来假设一进入页面就有3个敏感请求,那么第一个进来会使得_getUserInfoPromise(假设为p1),并且跳入授权页面,这样会导致,其他2个一起awaitp1这个promise,只有当p1跑通了才会接下来请求,那么p1在等什么?等用户点击授权啊。

    以上,有些模糊,之后会贴出实际代码。
    当然,这里贴个图帮助大家理解。


    小程序鉴权逻辑.jpg

    相关文章

      网友评论

        本文标题:小程序:没了getUserInfo我们该何去何从?

        本文链接:https://www.haomeiwen.com/subject/ziigdftx.html