微信小程序-同步登陆方案

记于:2024-03-11 上午
地点:浙江省·温州市·家里
天气:下雨

背景#

业务流程上需要等微信登陆(wx.login)后再执行后续操作,但是wx.login是异步的,如果简单地使用回调的方式,代码将会不简洁,同时也为了职责分离(将登陆与业务逻辑解耦),所以需要一个同步的方案。

思路#

根据网上的一些方案,比如使用Promise、async/await等,试过都失败了(可能是因为对这些技术不太熟);
最终选择从业务流程上入手,加一个加载页可以解决;
具体地:添加一个加载/入口(entry)页作为第一页面,在其中执行wx.login,成功则跳转到首页,如果失败则停留在加载页,并提示点击重新登陆。

代码#

entry.wxml

1
2
<!--pages/entry/entry.wxml-->
<button wx:if="{{initFail}}" bind:tap="onRetryTap" style="margin-top: 200px;">点击重试</button>

entry.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// pages/entry/entry.js
const consts = require('@/common/consts/consts.js')
const https = require('@/common/utils/https.js')
const base64 = require('@/common/utils/base64.js')
Page({
/**
* 页面的初始数据
*/
data: {
initFail: false,
userId: undefined
},
// data
// ================================================================================
// lifecycle
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('entry.onLoad: {}', JSON.stringify(options))
this.init()
},
// ================================================================================
// methods

// 初始化
init() {
console.log('init...')

var that = this

that.setData({ initFail: false })

wx.showLoading({ title: '初始化...', mask: true })

// 静默登录
wx.login({
success: (res) => {
console.log('wx.login.success: ' + JSON.stringify(res))
if (res.code) {
// 执行业务登录
https.post({
url: consts.apis.WXMP_LOGIN,
data: { code: res.code },
ignoreAuth: true,
success: function (res) {
if (res.data.data && res.data.data.token) {
var token = res.data.data.token
var userId = that.parseUserId(token)
// 保存到全局变量
getApp().globalData.token = token
getApp().globalData.userId = userId
// 保存到本地
wx.setStorageSync('token', token)
wx.setStorageSync('userId', userId)

// 跳转到首页
that.jumpToIndex()
} else {
that.setData({initFail: true})
}
},
fail: function(e) {
console.log('wxLogin.fail: {}', JSON.stringify(e))
that.setData({initFail: true})
},
complete: function(e) {
console.log('wxLogin.complete: {}', JSON.stringify(e))
wx.hideLoading()
}
})
} else {
console.log('登录失败!' + res.errMsg)
that.setData({initFail: true})
}
},
})
},
// 跳转到首页
jumpToIndex(options) {
console.log('jumpToIndex...{}', JSON.stringify(options))
wx.switchTab({ url: '/pages/index/index' })
},
// 当点击重试
onRetryTap(e) {
console.log('onRetryTap...')
this.init()
},
// 解析用户ID
parseUserId(token) {
// ...
}
})