天天看點

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

​簡短回顧一下微信小程式端的流程:

  1. 使用者通過掃碼進入小程式的鑒權頁面,更新狀态到ACCESSED已掃碼
  2. 使用者點選确認授權,微信通過wx.login()接口擷取第三方登入的必要資訊:Code登入憑證。

微信小程式主要為使用者授權行為提供互動功能,使用者在掃碼之後,提供一個互動UI,如下:

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

在使用 Abp.Zero 搭建第三方登入子產品(二):服務端開發 - 林曉lx - 部落格園 (cnblogs.com)中介紹了服務端已經搭建的接口,這次我們将調用Access和Authenticate,分别調用來完成已掃碼和已授權狀态的更新。

項目搭建

 首先使用vue-cli建立一個web項目,命名為mp-weixin

vue create -p dcloudio/uni-preset-vue mp-weixin           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

 在Pages下建立login/index.vue頁面,作為登入授權頁

目錄結構如下:

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

pages.json:

{
	"pages": [ //pages數組中第一項表示應用啟動頁,參考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "uni-app"
			}
		},
		{
			"path": "pages/login/index",
			"style": {
				"navigationBarTitleText": "授權頁"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	}
}
           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

 login目錄下建立ajaxRequire.ts, 建立request對象,這一對象将利用uni-axios-ts庫發送ajax請求

import axios from 'uni-axios-ts'
//發送網絡請求
export const request = async (url: string, methods, data: any, onProgress?: (e) => void, cancelToken?) => {
    let token = null
    let timeout = 3000;
    if (cancelToken) {
        token = cancelToken.token
        timeout = 0;
    }
    const service = axios.create()


    service.interceptors.request.use(
        (config) => {
            config.header['Content-Type'] = "application/json"
            return config
        },
        (error) => {
            Promise.reject(error)
        }
    )


    const re = await service.request({
        headers: { 'Content-Type': 'multipart/form-data' },
        url: url,
        method: methods,
        data: data,
        cancelToken: token,
        timeout: timeout,
        onUploadProgress: function (progressEvent) { //原生擷取上傳進度的事件
            if (progressEvent.lengthComputable) {
                if (onProgress) {
                    onProgress(progressEvent);
                }
            }
        },
    })
    return re as any;
}

///獲得取消令牌
export const getCancelToken = () => {
    const source = axios.CancelToken.source();
    return source;
}
           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

index.vue中建立loginExternalForms作為參數傳輸對象

export default {
  data() {
    return {
      loginExternalForms: {
        WeChat: {
          token: "",
          providerAccessCode: "",
        },
      }
    };
  }
}           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

onLoad函數中,option存有掃描小程式碼中的scene參數,将scene參數指派給token變量

onLoad(option) {
    this.loginExternalForms.WeChat.token = option.scene;
    this.start();
  },           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

start中我們調用Access接口,更改狀态至ACCESSED(已掃碼) ,若傳回成功,則提示點使用者點選确認授權,若傳回的結果異常"WechatMiniProgramLoginInvalidToken"時,表明此時小程式碼已過期,需在網頁端更新小程式碼。

async start() {
      var currentForms = this.loginExternalForms["WeChat"];
      this.loading = true;
      await request(`${this.prefix}/MiniProgram/Access`, "post", currentForms)
        .then((re) => {
          this.successMessage("您已掃描二維碼,請點選确認登入以完成");
        })
        .catch((c) => {
          var err = c.response?.data?.error?.message;
          if (err != null) {
            if (err == "WechatMiniProgramLoginInvalidToken") {
              this.isInvalid = true;
            } else {
              this.errorMessage(c.err);
            }
          }
        })
        .finally(() => {
          setTimeout(() => {
            this.loading = false;
          }, 1.5 * 1000);
        });
    },           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

Prefix是你的服務位址字首

prefix: "https://localhost:44311/api/services/app"           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

在Html中,我們建立授權登入與取消按鈕,僅當isInvalid 為true時可以點選授權

<button
        @click="handleWxLogin"
        :disabled="isInvalid || loading"
        class="sub-btn"
      >
        授權登入
      </button>

      <button @click="cancelWxLogin" :disabled="loading" class="sub-btn">
        取消
      </button>           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

建立 handleExternalLogin用于處理使用者點選授權登入後的邏輯,調用Authenticate接口,更新狀态至AUTHORIZED(已授權)在此之前需要調用uni.login擷取小程式登入憑證code。

有關uni.login函數,請參考官方文檔uni.login(OBJECT) | uni-app官網 (dcloud.io)

uniapp支援多種小程式,為了保留一定的擴充能力,handleExternalLogin函數中我們保留參數authProvider,已實作的微信小程式登入handleWxLogin函數調用時傳遞參數"WeChat",

async handleExternalLogin(authProvider) {
      var currentForms = this.loginExternalForms[authProvider];
      this.loading = true;
      await request(
        `${this.prefix}/MiniProgram/Authenticate`,
        "post",
        currentForms
      )
        .then((re) => {
          uni.redirectTo({
            url: "/pages/index/index",
          });
        })
        .catch((c) => {
          var err = c.response?.data?.error?.message;
          if (err != null) {
            if (err == "WechatMiniProgramLoginInvalidToken") {
              this.isInvalid = true;
            } else {
              this.errorMessage(c.err);
            }
          }
          setTimeout(() => {
            this.loading = false;
          }, 1.5 * 1000);
        });
    },


   async handleWxLogin() {
      const that = this;
      uni.login({
        provider: "weixin",
        success: (loginRes) => {
          that.loginExternalForms.WeChat.providerAccessCode = loginRes.code;
          that.handleExternalLogin("WeChat");
        },
      });
    },           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

建立取消登入函數

cancelWxLogin() {
      uni.redirectTo({
        url: "/pages/index/index",
      });
    },           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

執行成功通知函數

successMessage(value = "執行成功") {
      uni.showToast({
        title: value,
        icon: "success",
        duration: 1.5 * 1000,
      });
    },           
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

接下來簡單編寫一個界面,

界面将清晰的反映isInvalid與loading狀态時對應的UI互動:

正常

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

小程式碼過期 

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

整體測試

模拟器測試

打開網頁後,将圖像另存為

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

 在微信小程式調試工具,“通過二維碼編譯”

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

 等待手機界面顯示授權頁面後點選“授權登入”:

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

 GetCurrentUser接口傳回正确資料,并顯示于web頁面之上

使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發
使用 Abp.Zero 搭建第三方登入子產品(四):微信小程式開發

至此完成了小程式端的開發工作

項目位址

jevonsflash/abp-mp-auth (github.com)

結束語

小程式登入具有一定的擴充性,雖然通篇介紹微信小程式登入,但登入鑒權作為小程式抽象功能,uniapp內建了各個平台(微信、支付寶、百度、位元組跳動小程式)的登入接口,通過uni.login可以擷取相應平台的code