在 uni-app
中实现用户登录一次后在 token
过期前一直免登录的功能,可以通过以下几个关键步骤实现:本地持久化存储 Token、使用请求与响应拦截器自动处理 Token 刷新、以及在 App.vue
中结合 pages.json
设置登录状态跳转逻辑。
pages.json
配置说明pages.json
是 uni-app
的全局配置文件,用于定义页面路径、窗口样式、启动页等。虽然它不直接支持登录状态判断,但可以配合 App.vue
的 onLaunch
生命周期实现登录状态的控制。
pages.json
配置:{
"pages": [
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "主页"
}
},
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "登录"
}
}
],
"globalStyle": {
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#ffffff"
},
"window": {
"navigationBarTitleText": "uni-app"
},
"tabBar": {
"list": [
{
"pagePath": "pages/home/home",
"text": "主页"
},
{
"pagePath": "pages/user/user",
"text": "我的"
}
]
}
}
⚠️ 注意:
pages.json
中 第一个页面 是默认启动页(即 App 启动时进入的第一个页面)。我们会在App.vue
中动态决定跳转哪一个页面。
App.vue
的 onLaunch
生命周期是应用启动时的入口,适合在此判断用户是否已经登录(通过 Token 是否存在和是否过期),从而决定是否跳转到登录页或主页。
在登录成功后,需将 token
和 refreshToken
存入本地存储,并记录 token
的过期时间。
通过封装请求拦截器和响应拦截器,可以实现自动添加 token
到请求头、以及在 token
过期时自动刷新。
uni.addInterceptor('request', {
invoke(args) {
const token = uni.getStorageSync('token');
if (token) {
args.header = {
...args.header,
Authorization: `Bearer ${token}`
};
}
return args;
}
});
uni.addInterceptor('request', {
response: (res) => {
if (res.statusCode === 401) {
// token 过期,尝试刷新
return refreshToken().then((newToken) => {
uni.setStorageSync('token', newToken.token);
uni.setStorageSync('tokenExpireTime', Date.now() + newToken.expiresIn * 1000);
return uni.request(res.config); // 重新发送原请求
}).catch(() => {
uni.reLaunch({ url: '/pages/login/login' }); // 刷新失败则跳转登录页
});
}
return res;
}
});
refreshToken()
函数示例:async function refreshToken() {
const refreshToken = uni.getStorageSync('refreshToken');
const res = await uni.request({
url: 'https://api.example.com/refresh-token',
method: 'POST',
data: { refreshToken }
});
return res.data;
}
在每次请求前检查 token
是否即将过期,提前刷新以避免请求失败。
function isTokenExpired() {
const now = Date.now();
const expireTime = uni.getStorageSync('tokenExpireTime');
return now >= expireTime;
}
uni.addInterceptor('request', {
invoke(args) {
if (isTokenExpired()) {
return refreshToken().then((newToken) => {
uni.setStorageSync('token', newToken.token);
uni.setStorageSync('tokenExpireTime', Date.now() + newToken.expiresIn * 1000);
return uni.request(args); // 重新发送请求
}).catch(() => {
uni.reLaunch({ url: '/pages/login/login' });
});
}
return args;
}
});
AES
或 RSA
加密敏感数据(如 token
)。token
和 refreshToken
。步骤 | 内容 |
---|---|
1. pages.json |
配置页面路径和启动页 |
2. App.vue |
使用 onLaunch 判断登录状态 |
3. 登录逻辑 | 登录成功后存储 token 和 refresh token |
4. 请求拦截器 | 自动添加 token 到请求头 |
5. 响应拦截器 | 自动刷新 token 并重试请求 |
6. 主动刷新 token | 在请求前检查 token 是否即将过期 |
通过以上完整流程,你可以实现用户在 uni-app
中登录一次后,在 token
过期前免登录的功能。