小程序的登錄流程 登錄流程 代碼演練

登錄流程

1. 三個角色:

  • 小程序端
  • 微信自己的服務器
  • 公司的服務器

2. openid
openid:每一個微信用戶的唯一標識
openid一般不保存在客戶端,一般保存在服務器端。
我們自己的服務器會和微信的服務器進行通信。到時候微信的服務器就會返回一個session_key和openid,到時候我們的服務器會把這個openid存到數據庫中。

3. 登錄的過程:

  1. 我們的小程序端先調用接口 wx.login(),向微信的服務器發送請求,獲取到一個code,這個code在我們的客戶端是沒有用的。
    1.1 這個code的作用是發送到我們自己的服務器
    1.2 微信小程序端通過調用wx.request()將code發送到我們的服務器
    1.3 服務器拿到code和appid(一開始申請到的)和appsecret
    1.4 appsecret是怎麼獲取的:在小程序控制臺,和appid在一個地方,可以重置。
  2. 我們的服務器與微信的服務器進行一次溝通,將code+appid+appsecret這三個東西傳遞給微信的服務器,
  3. 微信的服務器會返回session_key和openid。服務器就拿到了openid,不會傳給客戶端,而是將openid存到服務器。
    3.1 有時候,公司希望不僅能用微信登錄,還可以用用戶名+密碼登錄小程序。
    3.2 一般用賬號+密碼登錄的時候,會在第一步,先讓用戶輸入用戶和密碼,服務器驗證通過以後,再將賬號+密碼+code發送給微信的服務器,換取openid;之後將openid+賬號+密碼存儲在數據庫的某個表中(t_user)。
  4. 服務器端驗證通過之後,會向客戶端返回一個token,登錄狀態。客戶端會把token保存起來。小程序中有個storage,一般將token保存在storage中。
  5. 下次再打開小程序的時候,就可以先從緩存中拿出token來,發送給服務器,驗證一下是否過期,不用每次打開都登錄一下了。如果過期了再登錄,沒過期的話就直接使用這個。
  6. 以後客戶端向服務器發送請求(請求需要在登錄的狀態下才會返回結果時),會攜帶token。服務器會根據token查詢openid或者session_key和其他數據。然後將數據返回給客戶端。

4. 簡化後的流程:

  1. 調用wx.login獲取code
  2. 調用wx.request發送code到我們自己的服務器(我們自己的服務器會返回一個登錄狀態的標識,比如token)
  3. 將登錄狀態的標識token進行存儲,以便下次使用
  4. 請求需要登錄狀態的接口時,帶上這個token。

5. 官方圖解

官方文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

代碼演練

接口:

  • 登錄接口
  • token是否過期的接口

登錄接口:

接口:/login
method:post
參數:code (如果想要賬號和密碼登錄的話,傳遞code+賬號+密碼)
返回:token

token是否過期的接口:

接口:/auth
method:post
參數:header,token,將token放在header中傳遞過去
返回值:
錯誤碼:
1001:沒有傳入token
1002:傳入錯誤的token
1003:token過期。

一般情況下,登錄在app.js中做,不用等到進入某個頁面再做。

wx.setStorage與wx.setStorageSync的區別:

  • wx.setStorage是異步的
  • wx.setStorageSync是同步的

小程序登錄的流程代碼大體如下:

// 註冊小程序的示例
const TOKEN = "token"; // 規範寫法,寫成常量,也可以抽取出來到一個常量文件中。
App({
  // 全局對象,一旦小程序關閉掉,會被回收
  globalData: {
    token: "", //token
  },

  // 小程序初始化完成時,加載完,一般在這裏進行登錄操作
  onLaunch: function(options) {
    // 3. 做登錄操作
    // 3.1 先在緩存中取出token,如果有,就驗證;沒有再登錄。
    const token = wx.getStorageSync(TOKEN);
    // 3.2 判斷token是否有值,並且判斷長度>0
    if (token && token.length > 0) { // 已經有token,需要驗證是否過期
      console.log("執行了驗證token操作");
      // 驗證token是否過期
      this.checkToken(token);
    } else {  // 還沒有token,所以得先登錄
      this.login(); // 登錄一下
    }
  },
  
  // 登錄的代碼
  login() {
    console.log("執行了登錄操作");
    wx.login({
      success: (res) => {
        console.log(res.code); // code只有5分鐘的有效期
        // 1. 獲取code
        const code = res.code;
        // 2. 將code發送給自己的服務器
        wx.request({
          url: 'http://123.207.32.32:3000/login', // 調用了別人的接口
          method: "post",
          data: {
            code,
          },
          success: (res) => {
            console.log(res); // 服務器會返回一個token
            // token的作用:在首頁,關於啥的頁面,都攜帶token才能查看某些內容
            // 拿到token,很多地方都要用,所以最好保存到全局中。
            // 3. 保存到全局
            const token = res.data.token;
            this.globalData.token = token; // 爲了this有效,要都寫成箭頭函數的形式
            console.log(this.globalData.token);
            // 4. token進行本地存儲(同步的)
            wx.setStorageSync(TOKEN, token);
          },
          fail: function(error) {
            console.log(error);
          }
        })
      }
    })
  },
  
  // 驗證token是否過期
  checkToken(token){
    wx.request({
      url: 'http://123.207.32.32:3000/auth',
      method: "post",
      header: {
        token,
      },
      success: (res) => {
        if(!res.data.errCode){  // token有效
          this.globalData.token = token;
        }else{  // token無效,得重新登錄
          this.login(); 
        }
      },
      fail: (error) => {
        console.log(error);
      }
    })
  }
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章