微信小程式授權登陸

2020-10-07 11:00:35

微信小程式登入授權

我們在專案中,登入,授權頁面,都必須要傳遞token值。
一般商品詳情頁面的商品收藏,加入購物車。購物車頁面都需要傳遞token。

token是什麼?

token是前端鑑權的一種方式,token由後端生成, 是有時效性的。

微信小程式如何登入授權,拿到token

第一步:登入流程
前端—>後端—>騰訊伺服器
wx.login—>wx.request—>後端—>小程式(騰訊)伺服器
小程式wx.login官方檔案https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
在這裡插入圖片描述

第二步:
登入---->檢測是否註冊—>沒有註冊先獲取使用者資訊進行註冊(寫入公司資料庫)—>進行登入
將登入彈框封裝成一個模板,進行參照
首先封裝好請求介面檔案

var API_BASE_URL = 'https://api.it120.cc'
var subDomain = 'mydomainname'   //專屬域名
let request = (url, needSubDomain, method, data) => {
  const _url = API_BASE_URL + (needSubDomain ? '/' + subDomain : '') + url
  return new Promise((resolve, reject) => {
    wx.request({
      url: _url,
      method: method,
      data: data,
      header: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      success(request) {
        resolve(request.data)
      },
      fail(error) {
        reject(error)
      },
      complete(aaa) {
        // 載入完成
      }
    })
  })
}

/**
 * 小程式的promise沒有finally方法,自己擴充套件下
 */
Promise.prototype.finally = function (callback) {
  var Promise = this.constructor;
  return this.then(
    function (value) {
      Promise.resolve(callback()).then(
        function () {
          return value;
        }
      );
    },
    function (reason) {
      Promise.resolve(callback()).then(
        function () {
          throw reason;
        }
      );
    }
  );
}

具體實現步驟

1.點選封裝的登入模板中的「允許」按鈕,執行processLogin方法

<button class="jbn_login" bindgetuserinfo="processLogin" open-type="getUserInfo">允許</button>
<!-- getUserInfo 獲取使用者資訊,可以從bindgetuserinfo回撥中獲取到使用者資訊 -->

processLogin方法:

const WXAPI = require('apifm-wxapi');
const index = require('../../utils/index.js')
  processLogin(e) {
    console.log(e.detail.userInfo)
    if (!e.detail.userInfo) {
      wx.showToast({
        title: '已取消',
        icon: "none"
      })
      return 
    }
    // 如果有userinfo ,就呼叫register註冊方法
    index.register(this)
  },


2.如果有userInfo,就呼叫register註冊方法,通過註冊把騰訊資訊寫入公司資料庫
註冊需要三個引數

  1. iv 加密值
  2. code
  3. encryptedData 加密資料
async function register(page) {
  let _this = this;
  wx.login({
    success: function (res) {
      let code = res.code; // 微信登入介面返回的 code 引數,下面註冊介面需要用到
      wx.getUserInfo({
        success: function (res) {
          let iv = res.iv;
          let encryptedData = res.encryptedData;
          let referrer = '' // 推薦人
          let referrer_storge = wx.getStorageSync('referrer');
          if (referrer_storge) {
            referrer = referrer_storge;
          }
          // 下面開始呼叫註冊介面
          WXAPI.register_complex({
            code: code,
            encryptedData: encryptedData,
            iv: iv,
            referrer: referrer
          }).then(function (res) {
            console.log(res)
            _this.login(page);
          })
        }
      })
    }
  })
}

3.執行登入的login方法,通過登入拿到token

async function login(page) {
  const _this = this
  wx.login({
    success: function (res) {
      WXAPI.login_wx(res.code).then(function (res) {
        if (res.code == 10000) {
          // 去註冊
          _this.register(page)
          return;
        }
        if (res.code != 0) {
          // 登入錯誤
          wx.showModal({
            title: '無法登入',
            content: res.msg,
            showCancel: false
          })
          return;
        }
        wx.setStorageSync('token', res.data.token)
        wx.setStorageSync('uid', res.data.uid)
        if (page) {
          page.onShow()
        }
      })
    }
  })
}


4.檢測登入狀態和token是否過期

//檢測token是否過期
//只檢測登入態(檢測微信返回)
async function checkSession(){
  return new Promise((resolve, reject) => {
      //通過內建方法檢測
    wx.checkSession({
      success() {
        return resolve(true)
      },
      fail() {
        return resolve(false)
      }
    })
  })
}
// 總體檢測登入狀態,包括token和微信登入態 返回 true 或false

//在app.js的onload生命週期通過index.checkHasLogined呼叫,如果過期

async function checkHasLogined() {
  //獲取本地儲存的token
  const token = wx.getStorageSync('token')
  //如果沒有token,直接返回false
  if (!token) {
    return false
  }

  //檢測微信登入態
  /**
   * 呼叫成功說明當前 session_key 未過期,呼叫失敗說明 session_key 已過期
   */
  const loggined = await checkSession()

  //如果沒有登入態,則移除token,並返回false
  if (!loggined) {
    wx.removeStorageSync('token')
    return false
  }

  //檢測登入token是否有效
  const checkTokenRes = await WXAPI.checkToken(token)

  //如果登入token無效,移除token並返回false
  if (checkTokenRes.code != 0) {
    wx.removeStorageSync('token')
    return false
  }
  
  //如果有token並且有效,並且微信登入態也有效則返回true
  return true
}

module.exports = {
  login: login,
  register: register,
  checkSession:checkSession,
  checkHasLogined:checkHasLogined
}