簡短回顧一下微信小程式端的流程:
- 使用者通過掃碼進入小程式的鑒權頁面,更新狀态到ACCESSED已掃碼
- 使用者點選确認授權,微信通過wx.login()接口擷取第三方登入的必要資訊:Code登入憑證。
微信小程式主要為使用者授權行為提供互動功能,使用者在掃碼之後,提供一個互動UI,如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyQjMmlDM3QjMmZGMlVzN5IjM0QTNwQGM0cDZldTN2czLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
在使用 Abp.Zero 搭建第三方登入子產品(二):服務端開發 - 林曉lx - 部落格園 (cnblogs.com)中介紹了服務端已經搭建的接口,這次我們将調用Access和Authenticate,分别調用來完成已掃碼和已授權狀态的更新。
項目搭建
首先使用vue-cli建立一個web項目,命名為mp-weixin
vue create -p dcloudio/uni-preset-vue mp-weixin
在Pages下建立login/index.vue頁面,作為登入授權頁
目錄結構如下:
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"
}
}
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;
}
index.vue中建立loginExternalForms作為參數傳輸對象
export default {
data() {
return {
loginExternalForms: {
WeChat: {
token: "",
providerAccessCode: "",
},
}
};
}
}
onLoad函數中,option存有掃描小程式碼中的scene參數,将scene參數指派給token變量
onLoad(option) {
this.loginExternalForms.WeChat.token = option.scene;
this.start();
},
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);
});
},
Prefix是你的服務位址字首
prefix: "https://localhost:44311/api/services/app"
在Html中,我們建立授權登入與取消按鈕,僅當isInvalid 為true時可以點選授權
<button
@click="handleWxLogin"
:disabled="isInvalid || loading"
class="sub-btn"
>
授權登入
</button>
<button @click="cancelWxLogin" :disabled="loading" class="sub-btn">
取消
</button>
建立 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");
},
});
},
建立取消登入函數
cancelWxLogin() {
uni.redirectTo({
url: "/pages/index/index",
});
},
執行成功通知函數
successMessage(value = "執行成功") {
uni.showToast({
title: value,
icon: "success",
duration: 1.5 * 1000,
});
},
接下來簡單編寫一個界面,
界面将清晰的反映isInvalid與loading狀态時對應的UI互動:
正常
小程式碼過期
整體測試
模拟器測試
打開網頁後,将圖像另存為
在微信小程式調試工具,“通過二維碼編譯”
等待手機界面顯示授權頁面後點選“授權登入”:
GetCurrentUser接口傳回正确資料,并顯示于web頁面之上
至此完成了小程式端的開發工作
項目位址
jevonsflash/abp-mp-auth (github.com)
結束語
小程式登入具有一定的擴充性,雖然通篇介紹微信小程式登入,但登入鑒權作為小程式抽象功能,uniapp內建了各個平台(微信、支付寶、百度、位元組跳動小程式)的登入接口,通過uni.login可以擷取相應平台的code