加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

小程序的登录与静默续期

发布时间:2020-12-14 19:23:50 所属栏目:资源 来源:网络整理
导读:每一个有数据交互的小程序,都会涉及到登录、token 等问题,openid 又是什么呢?怎么使用静默续期,来提升用户体验呢? 小程序登录 登录时序 一切的一切,都要从这么一张小程序登录时序图说起: 通常情况下,我们的小程序都会有业务身份,如何将微信帐号和业

每一个有数据交互的小程序,都会涉及到登录、token 等问题,openid 又是什么呢?怎么使用静默续期,来提升用户体验呢?

小程序登录


登录时序

一切的一切,都要从这么一张小程序登录时序图说起:

通常情况下,我们的小程序都会有业务身份,如何将微信帐号和业务身份关联起来呢?这个时候我们需要上图的步骤:

  1. 小程序调用wx.login()获取临时登录凭证code
  2. 小程序将code传到开发者服务器。
  3. 开发者服务器以code换取用户唯一标识openid和会话密钥session_key
  4. 开发者服务器可绑定微信用户身份id和业务用户身份。
  5. 开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

相关数据或参数

上面的登录时序中,我们会涉及到一些数据和参数,先来了解下它们都是用来做啥的。

临时登录凭证 code
在小程序中调用wx.login(),能拿到一个code作为用户登录凭证(有效期五分钟)。在开发者服务器后台,开发者可使用code换取openidsession_key等信息(code只能使用一次)。

code的设计,主要用于防止黑客使用穷举等方式把业务侧个人信息数据全拉走。

AppId 与 AppSecret
为了确保拿code过来换取身份信息的人就是对应的小程序开发者,到微信服务器的请求要同时带上AppIdAppSecret

session_key
会话密钥session_key是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。

设计session_key主要是为了节省流程消耗,如果每次都通过小程序前端wx.login()生成微信登录凭证code去微信服务器请求信息,步骤太多会造成整体耗时比较严重。

使用接口wx.checkSession()可以校验session_key是否有效。用户越频繁使用小程序,session_key有效期越长。session_key失效时,可以通过重新执行登录流程获取有效的session_key

openid
openid是微信用户id,可以用这个id来区分不同的微信用户。
微信针对不同的用户在不同的应用下都有唯一的一个openid,但是要想确定用户是不是同一个用户,就需要靠unionid来区分。

unionid
如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性。同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

加锁的登录

在某些情况下,我们或许多个地方会同时触发登录逻辑(如多个接口同时拉取,发现登录态过期的情况)。一般来说,我们会简单地给请求加个锁来解决:

  1. 使用isLogining来标志是否请求中。
  2. 方法返回 Promise,登录态过期时静默续期后重新发起。
  3. 使用sessionId来记录业务侧的登录态。
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
// session 参数 key(后台吐回)
export const SESSION_KEY = 'sessionId';
let isLogining = false;
export function doLogin() {
return new Promise((resolve,reject) => {
const session = wx.getStorageSync(SESSION_KEY);
if (session) {
// 缓存中有 session
resolve();
} else if (isLogining) {
// 正在登录中,请求轮询稍后,避免重复调用登录接口
setTimeout(() => {
doLogin()
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
});
},500);
} else {
isLogining = true;
wx.login({
success: res) => {
if (res.code) {
const reqData: ILoginRequest = {
code: res.code
}
wx.request({
url: API.login,
data: reqData,
// method: "POST",
success: resp) => {
const data = resp.data;
isLogining = false;
// 保存登录态
if (data.return_code === 0) {
wx.setStorageSync(SESSION_KEY,data[SESSION_KEY]);
resolve();
} else {
reject(data.return_msg);
}
},
fail: err => {
// 登录失败,解除锁,防止死锁
isLogining = false;
reject(err);
}
});
} else {
// 登录失败,解除锁,防止死锁
isLogining = false;
reject();
}
},
fail: err) => {
// 登录失败,解除锁,防止死锁
isLogining = false;
reject(err);
}
});
}
});
}

登录态静默续期的实现


checkSession

前面也提到,微信不会把session_key的有效期告知开发者,因此需要使用接口wx.checkSession()来校验session_key是否有效。

这里我们:

    isCheckingSession来标志是否查询中。
  1. 返回 Promise。
  2. 使用isSessionFresh来标志session_key是否有效。
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
import { doLogin } from "./doLogin";
import { SESSION_KEY } "./doLogin";
let isCheckingSession = let isSessionFresh = false;
function checkSession(): Promise<string> {
if (isCheckingSession) {
setTimeout(() => {
checkSession()
.then(if (!isSessionFresh && session) {
isCheckingSession = true;
wx.checkSession({
success: () => {
// session_key 未过期,并且在本生命周期一直有效
isSessionFresh = true;
resolve();
},150);">// session_key 已经失效,需要重新执行登录流程
wx.removeStorage({
key: "skey",
complete: () => {
doLogin()
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
}
});
},
complete: () => {
isCheckingSession = false;
}
});
} else {
doLogin()
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
});
}
});
}

静默续期的接口请求

至此,我们可以封装一个简单的接口,来在每次登录态过期的时候自动续期:

  1. 在请求前,使用checkSession()检车本次周期内session_key是否有效,无效则doLogin()拉起登录获取sessionId
  2. 请求接口,若返回特定登录态失效错误码(此处假设为LOGIN_FAIL_CODE),则sessionId
  3. 使用tryLoginCount来标志重试次数,TRY_LOGIN_LIMIT来标志重试次数上限,避免进入死循环。
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
至此,我们大概包装了一个能自动登录或是进行静默续期的一个请求接口。

参考

  • 小程序登录API
  • 《小程序开发指南》

结束语


小程序的登录和登录态管理,大概是大部分小程序都需要的能力。codesession_key的设计,做了哪些事情来保护用户的数据。
如何在全局范围地保证登录态的有效性,微信侧的登录态也好,业务侧的登录态也好,静默续期的能力能给用户带来不少的体验提升。

查看Github有更多内容噢:https://github.com/godbasin

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读