乐趣区

小程序篇2登录获取用户信息

登录和获取用户信息是小程序中最基本的两步操作,但是由于之前小程序官方开始时的设计缺陷,导致很多开发者将登录和获取用户信息绑定使用,尽管后来小程序 wx.getUserInfo 接口调整为:在用户未授权过的情况下调用此接口,将不再出现授权弹窗,会直接进入 fail 回调,但是改了之后,依旧有不少开发者对这两步的概念混淆不清,接下来这篇文章将会详细介绍小程序这两步操作

登录

wx.login() 用来做登录的方法,调用接口获取登录凭证,code 发送给后端用于置换 session_key 和 openid 等数据,接下来看看小程序的整个登录流程是怎样的:

这是小程序官方的一张登录流程图,现在就来解读一下这个流程

  • 前端 wx.login() 获取 code,调用后端接口,将得到的 code 发送到后端
  • 后端调用微信接口服务,用 appid+appsecret+code 发送过去,置换到 session_key+openid,以前是不能置换 unionid 的,但是现在在满足以下条件可以置换到 unionid
  1. 在微信开放平台下存在同主体的 App、公众号、小程序
  2. 用户关注了某个相同主体公众号,或曾经在某个相同主体 App、公众号上进行过微信登录授权

同时满足以上两个条件就能拿到用户 unionid,这样一来,就能在 wx.login() 准确识别出用户是谁

  • 自定登录态与 openid 和 session_key 关联,实际就是生成一个与 openid,session_key 关联的 token,下发给前端
  • 前端将后端下发的 token 存入缓存,在后面的接口请求中带上自定登录态

以上就是小程序的整个登录流程,可以看到其实并不是一定要 wx.getUserInfo() 才能拿到用户的信息,在特定的条件下,通过 wx.login() 的调用拿到 unionId 也能后端数据库里拿到用户信息

获取用户信息

wx.getUserInfo() 以前调用时是会弹出授权弹框的,根据用户的授权与否进入对应的回调函数,但是后来微信发现开发者滥用 wx.getUserInfo() 方法,不授权用户信息不能使用小程序,现在就只能通过 button 组件 open-type=”getUserInfo” 触发授权弹窗,授权后能获得用户信息以及用户信息的加密数据,将用户信息的加密数据发送到后端,后端通过 wx.login() 的 code 置换到的 session_key 对加密数据进行解密就能拿到用户的完整信息,这一步其实是对第一步的补充,当 wx.login() 无法确认用户的时候时候才会执行到这一步,如果在 wx.login() 可以确认用户信息时,就可以不用执行这一步,实现用户的无感登录。

注意点:根据小程序官方最近发布的文档来看,小程序不能用户进入小程序时就弹登录框要求用户登录才能体验小程序,这种操作审核会被拒,要用户在体验一定的小程序功能后,才能引导用户去登录授权用户信息,具体文档地址

token 过期重登

以往我们写网页应用时,当后端下发的 token 失效时,请求接口会得到 403 错误码,然后前端接到返回的错误码时就会跳到登录页要求用户重新登录,但是在小程序当 token 失效时,需要跳到一个登录页重新登录吗?明显不需要,因为小程序本身就没有账号密码登录,因此登录失效了直接做一个无感的重登操作就行了,除非某些小程序在并没有依赖微信的登录信息,而是小程序里面内置自己的用户登录信息,这时候就需要跳到一个登录页面进行重登,但是这样的小程序还是少数,接下来就来看看如何小程序是如何做无感重登的。

直接来看代码:

const Fly = require('../libs/flyio')
const fly = new Fly()
const newFly = new Fly()
let time = 0
let baseUrl = 'xxxxx'
fly.interceptors.request.use((request) => {wx.showNavigationBarLoading()
  request.headers['token'] = wx.getStorageSync('token')
  request.baseURL = baseUrl
  return request
})
newFly.interceptors.request.use((request) => {wx.showNavigationBarLoading()
  request.headers['token'] = wx.getStorageSync('token')
  request.baseURL = baseUrl
  return request
})
fly.interceptors.response.use((response, promise) => {wx.hideNavigationBarLoading()
    return promise.resolve(response.data)
  },
  function (err, promise) {wx.hideNavigationBarLoading()
    // session 或者 session_key 失效的时候重新登录
    if (err.status === 403) {
      // 锁定当前实例,后续请求会在拦截器外排队
      this.lock()
      // 当出现未认证的情况时重新登录, 超过三次抛出错误
      if (time > 3) {
        time = 0
        return promise.reject(err.message + `(${err.status})`)
      }
      return new Promise((resolve, reject) => {
        wx.login({success: (e) => {
            let options = {'code': e.code}
            resolve(options)
          }
        })
      }).then((options) => {return newFly.post('/login', options).then(info => {wx.setStorageSync('token', info.token)
          time++
          // 解锁后,会继续发起请求队列中的任务
          this.unlock()
          // 重新请求失败的请求
          return fly.request(err.request)
        })
      })
    }
  }
)

export {fly}

上面的代码展示的就是小程序 token 过期重登的过程,代码不多,关键的地方也加上了注释,很容易理解,这里面最关键的就是使用了 flyio 这个网络请求库,利用这个库做的过期重登,这是一个基于 Promise 的、强大的、支持多种 JavaScript 运行时的 http 请求库,可以使用一份 http 请求代码在浏览器、微信小程序、Weex、Node、React Native、快应用中都能正常运行,在小程序中使用这个库十分方便。这段代码为了避免死循环,因此用了一个计数,超过三次就不会再重试登录,直接抛错

总结

本篇文章主要介绍了小程序的登录流程、获取用户信息、以及登录过期重登的相关内容,这里介绍的只是基础的通用的流程,实际上每个小程序的业务可能不太一样,因此在具体应用需要根据具体业务再行调整。
如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞

退出移动版