传统登录逻辑

  1. 输入账号密码,发送给服务端
  2. 服务端校验后,下发一个表示登录状态的token给客户端
  3. 每次发送需要登录的请求时,携带这个token
  4. 当服务端认为token过期,返回前端信息,提示用户重新登陆

登录的本质是一个有用户登录状态信息的身份标识

微信小程序登录

在微信小程序中,可以通过微信提供的登录能力直接获取到微信官方所提供的身份标识
如此便可跳过密码账号的流程,简化传统登录过程

微信小程序的登录流程

微信小程序的登录流程

  1. 通过 wx.login 获取到用户的 code,判断用户是否授权读取用户信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 登录,完成后执行请求队列
var login = function () {
if (!login_loading) {
login_loading = true;
wx.login({
success: function (res) {
if (res.code) {
Api.login(res.code).then((loginRequest) => {
try {
wx.setStorageSync("session_key", loginRequest.wechat_auth);
} catch (e) {}
request_queue.forEach((request) => {
request.resolve(loginRequest.wechat_auth);
});
store.dispatch("getUser");
});
} else {
console.log("登录失败!" + res.errMsg);
}
},
});
}
};
  1. 使用 wx.request 方法请求服务端,服务端将 appid,appsecret 和 code 一起发送到微信服务器
1
2
3
4
5
export function login(code) {
return request.post("url", {
code: code,
});
}
  1. 微信服务器将 openid 以及本次登录的会话密钥 session_key 返回给服务端(session_key 是对用户数据进行加密签字的密钥,为了自身应用的安全,session_key 不应该在网络上进行传输,不应该传输到客户端上)
  2. 服务端从数据库中查找 openid ,如果没有查到记录,说明用户没有注册
  3. 服务端查找到 openid 后,生成该用户的 session 返回给小程序
1
// 第一步代码中的Api.login().then()
  1. 小程序将 session 存到 wx.storage 中
1
2
3
4
// 第一步代码中的Api.login().then()
try {
wx.setStorageSync("session_key", loginRequest.wechat_auth);
} catch (e) {}
  1. 之后的请求,小程序先从 storage 中读取到 session 并带给服务端
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
// 全局变量
var login_loading = false; // 登录标识
var request_queue = []; // 正在登录时的请求队列
var session_key = ""; // 用户session,每次请求时需检测本地是否存储,并且是否过期

// fly.interceptors.request.use中的代码
// 设置每次请求携带session
fly.interceptors.request.use(async (request) => {
// 查看网络状态 将wx.getNetworkType封装为promese
let netType = await getNetType();
if (netType === "none") {
// 无网络
wx.showToast({
title: "无网络",
icon: "none",
duration: 1000,
});
return request;
}
// 获取session_key
try {
session_key = wx.getStorageSync("session_key");
} catch (e) {}

if (request.url === "url") {
// 登录时不需检测session_key
return request;
}
// 同步检测session_key是否过期
var sessionkeyCheck = await new Promise((resolve) => {
wx.checkSession({
success: function () {
resolve(true);
},
fail: function () {
resolve(false);
},
});
});
// 小程序端判断登录状态并且设置请求携带session
// 有session_key存储在本地,且未过期
if (session_key && sessionkeyCheck) {
request.body = Object.assign({ wechat_auth: session_key }, request.body);
return request;
} else {
// 没有session_key存储在本地时,或是session_key过期
session_key = await new Promise((resolve, reject) => {
request_queue.push({ resolve, reject });
login();
});
request.body = Object.assign({ wechat_auth: session_key }, request.body);
return request;
}
});
  1. 服务端比对 session 记录,校验有效期

微信小程序的登录流程

检查登录状态

以上登录逻辑中的第 8 个步骤即是检查登录状态,除此之外,微信提供了 wx.checkSession 方法可以检查微信登录状态是否过期

  • 如果过期,则发起登录流程
  • 如过不过期,则继续使用本地保存的自定义登录状态

检查登录状态

(其实看起来也并不简单,用户简单了开发者就麻烦一点)

参考引用
https://mp.weixin.qq.com/s/2d2ly1A7F62-mKl2Qldycw