微信小程序登录流程梳理总结

2,755 阅读4分钟

前言

写博客主要是用来总结、巩固知识点,加深自己对这个知识点的理解。同时希望能帮助到有需要的人。如有不正确的地方。可以在评论区指出。你们的支持。是我不断进步的源泉。

小程序登录流程

这里引用下官方的一张登录流程图,我就按照登录流程图来讲下我的理解。

alt

第一步

客户端(小程序)获取当前微信登录用户的登录凭证(code)

可通过wx.login api获得。这里有地方需要注意

1.wx.login不会弹授权弹框

2.wx.login换取的code只能使用一次,如果需要新code只能重新调用wx.login接口

    wx.login({
        success:(res)=>{
            let code= res.code
        }
    })

第二步

通过上一步获得的临时登录凭证传给服务器端获取openid和session_key.服务器端需要通过appid、appsecret、(这里的数据可以从小程序管理后台获得)code(第一步获取到的code)向微信服务端发送请求获取seeeion_key和openid。为了安全。建议将获得的session_key加密后再传给客户端。

第三步

客户端获得加密后的登录态后把登录态存在本地以便后面进行业务请求。由于小程序中不存在cookie机制。所以可以把登录态存储在storage中。

以上就是微信官方登录流程图的一个大体过程。

但是在实际应用中可能要复杂点?我们接下来看。

登录态在实际应用中的维护

这里看一下微信官方的说明

通过 wx.login 接口获得的用户登录态拥有一定的时效性。
用户越久未使用小程序,用户登录态越有可能失效。
反之如果用户一直在使用小程序,则用户登录态一直保持有效。
具体时效逻辑由微信维护,对开发者透明。
开发者只需要调用 wx.checkSession 接口检测当前用户登录态是否有效。

这说明如果用户一直在使用小程序。登录态就不会过期。反之就会过期。这里可以通过wx.checkSession api 来判断登录态是否过期。

接下来上代码。来看下在应用中的登录态维护。

目前在小程序中需要拉起微信登录授权的弹框。需要在wxml文件中调用button组件来调用:如下

<button bindgetuserinfo="getInfo"  hover-class="none" open-type="getUserInfo"></button>

这样用户点击按钮的时候会弹出授权获取用户信息的弹窗。用户点击允许我们就可以拿到数据进行登录并进行业务请求。 如果点击拒绝可以获取不需要登录可查看的数据请求,并安利用户拒绝后的结果。重新引导用户进行授权。

下面是用户非首次进入应用的一个登录态维护(首次进入通过button来授权。所以success回调是不会执行的。直接fail的回调。)

// 小程序启动判断用户是否授权,根据是否授权来请求不同的业务数据
wx.getSetting({
  success: (res) => {
    //用户已授权
    if (res.authSetting['scope.userInfo']) {
      // 判断登录态是否过期
      wx.checkSession({
        // 登录态未过期,直接进行业务请求
        success: (res) => {
          //业务请求代码。。。
        },
        // 登录态已过期 。重新调用wx.login进行登录换取code
        fail: (res) => {
        // 可以在这里进行重新登录后的回调
          wx.login({
            success: function(res) {
              let code = res.code;
            }
          })
        }
      })
    }
    // 为授权 
    else {
      // 执行未授权的业务代码
    }
  }
})

附上登录态过期的回调。

  /**
   * 登录失败后重新登录
   */
  getToken: function(fn) {
    let that = this;
    let getLogin = new Promise((resolve, reject) => {
      //登录获取code
      wx.login({
        success: function(res) {
          var code = res.code;
          that.globalData.code = code;
          resolve([fn, code]);
        },
        fail: function(res) {
          reject();
        }
      })
    });
    getLogin.then(([fn, code]) => {
      return new Promise((resolve, reject) => {
        //使用该api需要在页面通过button组件触发授权弹窗
        wx.getUserInfo({
          success: function(res) {
            //这里的iv,encryptedData等数据是用来服务器端进行解密的。
            let requestData = {
              "Data": {
                "IV": res.iv,
                "EncryptedData": res.encryptedData,
                "JsCode": code,
              },
            }
            //发送请求
            wx.request({
              url: that.apiList.login.getLogin,
              data: requestData,
              method: "POST",
              success: function(res) {
              //获取到自定义登录态存入storage
                if (res.data && res.data.Success) {
                  that.globalData.token = res.data.Data.Key;
                  wx.setStorageSync('LoginSessionKey', res.data.Data.Key);
                  resolve(fn);
                } else {
                  reject();
                }
              },
              fail: function() {
                Hq.tipMaskNoneIcon('您的网络开小差了');
              }
            })
          }
       
        })
      });
    }).then((fn) => {
      that.getCountryInfo(fn);
    }, function() {}))
  },

  //执行fn回调函数
  getCountryInfo: function(fn) {
    if (typeof fn == 'function') {
      //登录成功后进行业务请求。
      fn();
    } else {
      Hq.afterSend();
    }
  },

以上就是我的一些理解。有语句不通,逻辑不清晰的地方,请不吝留言赐教!

感谢阅读我的文章!