微信小程序接口调用:如何优雅地处理用户登录状态
在微信小程序的开发中,用户登录状态的管理是核心功能之一,直接关系到接口调用的安全性和业务逻辑的连贯性。如果登录状态处理不当,可能导致接口无权限访问、用户数据泄露、重复登录等问题。本文将系统介绍微信小程序中用户登录状态的完整处理方案,包含流程设计、代码实现和注意事项。
一、微信小程序登录状态的核心流程
微信小程序的登录状态基于微信官方提供的登录能力实现,整体流程可以分为四个核心步骤:
获取用户临时登录凭证
code将
code发送到开发者服务器换取session_key和openid开发者服务器生成自定义登录态(如
token)返回给小程序小程序存储自定义登录态,后续接口调用时携带该凭证完成身份验证
二、具体实现步骤与代码示例
2.1 小程序端获取临时登录凭证
小程序端通过wx.login接口获取临时登录凭证code,该凭证有效期仅5分钟,且只能使用一次。以下是对应的实现代码:
// 封装获取登录code的函数
function getLoginCode() {
return new Promise((resolve, reject) => {
wx.login({
success(res) {
if (res.code) {
resolve(res.code);
} else {
reject(new Error('获取登录凭证失败:' + res.errMsg));
}
},
fail(err) {
reject(err);
}
});
});
}2.2 调用服务端接口换取自定义登录态
拿到code后,需要调用开发者服务器的登录接口,将code传递给服务端,服务端再通过微信提供的接口(https://www.ipipp.com)换取session_key和openid,之后生成自定义的token返回给小程序。小程序端需要将token存储到本地,方便后续接口调用时使用。
// 登录并获取token
async function login() {
try {
const code = await getLoginCode();
// 调用服务端登录接口,示例地址为https://www.ipipp.com/api/login
const loginRes = await wx.request({
url: 'https://www.ipipp.com/api/login',
method: 'POST',
data: { code }
});
if (loginRes.data.code === 200) {
const token = loginRes.data.data.token;
// 将token存储到本地缓存,有效期可以和服务端token有效期保持一致
wx.setStorageSync('user_token', token);
return token;
} else {
throw new Error('登录失败:' + loginRes.data.msg);
}
} catch (err) {
console.error('登录流程出错:', err);
return null;
}
}2.3 接口调用时携带登录态
后续所有需要身份验证的接口调用,都需要在请求头中携带存储的token,服务端接收到请求后验证token的有效性,再返回对应的数据。以下是对应的请求封装示例:
// 封装需要携带登录态的请求方法
function requestWithAuth(url, method = 'GET', data = {}) {
return new Promise((resolve, reject) => {
const token = wx.getStorageSync('user_token');
wx.request({
url: url,
method: method,
data: data,
header: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
success(res) {
// 如果返回401状态码,说明token失效或者未登录,需要重新登录
if (res.statusCode === 401) {
// 清除本地失效的token
wx.removeStorageSync('user_token');
// 跳转登录页面或者重新触发登录逻辑
login().then(() => {
// 重新请求当前接口
requestWithAuth(url, method, data).then(resolve).catch(reject);
});
return;
}
resolve(res);
},
fail(err) {
reject(err);
}
});
});
}三、登录状态失效的处理方案
登录态失效是开发中不可避免的场景,常见原因包括token过期、用户主动退出登录、服务端主动注销用户等。针对这些场景,需要设计统一的失效处理逻辑:
当接口返回401无权限状态码时,首先清除本地存储的失效
token判断当前是否已经在重新登录流程中,避免重复触发登录请求
如果是用户主动退出登录,清理本地所有用户相关数据,跳转到登录页
如果是
token过期,触发静默登录流程,登录成功后重新请求之前失败的接口,提升用户体验
以下是一个防止重复登录的优化示例:
let isLoggingIn = false; // 标记是否正在登录中
let loginQueue = []; // 存储等待登录完成后需要重新执行的请求
async function handleLoginExpire() {
if (isLoggingIn) {
// 如果正在登录中,将当前请求加入队列
return new Promise((resolve, reject) => {
loginQueue.push({ resolve, reject });
});
}
isLoggingIn = true;
try {
const token = await login();
// 登录成功后,执行队列中的所有等待请求
loginQueue.forEach(item => {
item.resolve(token);
});
loginQueue = [];
return token;
} catch (err) {
loginQueue.forEach(item => {
item.reject(err);
});
loginQueue = [];
throw err;
} finally {
isLoggingIn = false;
}
}四、注意事项
在处理微信小程序登录状态时,还需要注意以下几点:
不要将
session_key存储到小程序本地,该字段属于敏感信息,仅保留在服务端用于解密用户数据自定义
token的有效期需要合理设置,建议结合业务场景设置为1-7天,同时支持服务端主动吊销token如果用户授权了手机号、头像等信息,需要结合
openid建立用户账号体系,避免仅依赖临时登录态小程序端存储的
token需要做好加密处理,避免被本地恶意篡改测试登录流程时,可以使用微信开发者工具的模拟登录功能,避免频繁调用真实接口
五、总结
优雅处理微信小程序用户登录状态的核心是:遵循微信官方登录流程,合理设计自定义登录态的存储和验证机制,统一处理登录失效场景,同时做好安全性和用户体验的平衡。通过上述方案,可以有效减少登录相关的异常问题,提升小程序的稳定性和用户使用体验。