当前位置: 首页 > news >正文

uni-app开发app保持登录状态

uni-app 中实现用户登录一次后在 token 过期前一直免登录的功能,可以通过以下几个关键步骤实现:本地持久化存储 Token、使用请求与响应拦截器自动处理 Token 刷新、以及在 App.vue 中结合 pages.json 设置登录状态跳转逻辑


✅ 一、pages.json 配置说明

pages.jsonuni-app 的全局配置文件,用于定义页面路径、窗口样式、启动页等。虽然它不直接支持登录状态判断,但可以配合 App.vueonLaunch 生命周期实现登录状态的控制。

示例 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 中实现登录状态判断

App.vueonLaunch 生命周期是应用启动时的入口,适合在此判断用户是否已经登录(通过 Token 是否存在和是否过期),从而决定是否跳转到登录页或主页。

示例代码(App.vue):

<script>
export default {onLaunch() {// 检查本地是否存在有效的 tokenconst token = uni.getStorageSync('token');const expireTime = uni.getStorageSync('tokenExpireTime');if (token && Date.now() < expireTime) {// token 有效,跳转到主页uni.reLaunch({url: '/pages/home/home'});} else {// token 无效或不存在,跳转到登录页uni.reLaunch({url: '/pages/login/login'});}}
}
</script>

✅ 三、登录与 Token 存储逻辑

在登录成功后,需将 tokenrefreshToken 存入本地存储,并记录 token 的过期时间。

示例代码(login.vue):

<script>
export default {methods: {async handleLogin() {const res = await uni.request({url: 'https://api.example.com/login',method: 'POST',data: {username: this.username,password: this.password}});const { token, refreshToken, expiresIn } = res.data;// 存储 token 和 refresh tokenuni.setStorageSync('token', token);uni.setStorageSync('refreshToken', refreshToken);// 计算 token 过期时间(单位:毫秒)const expireTime = Date.now() + expiresIn * 1000;uni.setStorageSync('tokenExpireTime', expireTime);// 登录成功后跳转到主页uni.reLaunch({url: '/pages/home/home'});}}
}
</script>

✅ 四、请求与响应拦截器自动处理 Token

通过封装请求拦截器和响应拦截器,可以实现自动添加 token 到请求头、以及在 token 过期时自动刷新。

请求拦截器(添加 token)

uni.addInterceptor('request', {invoke(args) {const token = uni.getStorageSync('token');if (token) {args.header = {...args.header,Authorization: `Bearer ${token}`};}return args;}
});

响应拦截器(token 刷新)

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 即将过期时主动刷新

在每次请求前检查 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 锁机制:防止多个请求同时触发刷新。
  • 清理本地存储:用户登出时清除 token 和 refreshToken
  • 敏感信息不要明文存储

✅ 七、总结

步骤内容
1. pages.json配置页面路径和启动页
2. App.vue使用 onLaunch 判断登录状态
3. 登录逻辑登录成功后存储 token 和 refresh token
4. 请求拦截器自动添加 token 到请求头
5. 响应拦截器自动刷新 token 并重试请求
6. 主动刷新 token在请求前检查 token 是否即将过期

通过以上完整流程,你可以实现用户在 uni-app 中登录一次后,在 token 过期前免登录的功能。

http://www.lqws.cn/news/584857.html

相关文章:

  • 【C++】简单学——模板初阶
  • 中证500股指期货一手多少钱呢?风险如何?
  • 易语言-登录UI演示
  • 一个代理对象被调用时,方法调用的链路是怎样的?
  • 【Kafka使用方式以及原理】
  • 安卓获取图片(相机拍摄/相册选择)
  • Android Telephony 网络状态中的 NAS 信息
  • window显示驱动开发—在注册表中设置 DXGI 信息
  • 【C语言】知识总结·内存函数
  • 三态门Multisim电路仿真——硬件工程师笔记
  • 优雅草蜻蜓HR人才招聘系统v2.0.9上线概要 -优雅草新产品上线
  • Amazon Athena:无服务器交互式查询服务的终极解决方案
  • 33. 搜索旋转排序数组
  • pytorch底层原理学习--PyTorch 架构梳理
  • FreePDFv3.0.0:颠覆你的文献阅读习惯
  • 16014.rtsp推流服务器
  • C++ 第四阶段 STL 容器 - 第五讲:详解 std::set 与 std::unordered_set
  • TDH社区开发版安装教程
  • [学习]M-QAM的数学原理与调制解调原理详解(仿真示例)
  • [面试]手写题-Promise.all() Promise.race()
  • 机器学习20-线性网络思考
  • 第三十六章 CAN——控制器局域网络接口
  • 字节跳动 C++ QT PC客户端面试
  • 论文中用matplotlib画的图,如何保持大小一致。
  • Vue2中使用DHTMLX Gantt
  • 深入理解Webpack的灵魂:Tapable插件架构解析
  • 使用Dirichlet分布进行随机初始化
  • 文心大模型 4.5 系列开源首发:技术深度解析与应用指南
  • StackGAN(堆叠生成对抗网络)
  • vscode 改注释的颜色,默认是灰色的,想改成红色