美文网首页程序员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