Flutter中使用http请求时Token过期如何自动跳转至登录页?
Token过期未自动跳转登录页,仅显示"Token Expired"异常文本问题排查
问题描述
当用户Token过期时,应用未按预期跳转至登录页面,而是在Widget中直接显示"Token Expired"的异常提示文本。
排查方向及代码检查点
1. 全局请求拦截器的Token过期处理
检查API请求拦截器(如Dio Interceptor)中是否仅抛出异常/显示文本,未触发跳转逻辑:
- 错误示例(仅提示无跳转):
if (response.statusCode == 401) { // 仅显示提示,未执行跳转 showSnackBar(context, "Token Expired"); }
- 修正逻辑:
if (response.statusCode == 401) { // 清除本地过期Token await SharedPreferences.getInstance().then((prefs) => prefs.remove("token")); // 跳转登录页并清空路由栈 Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => LoginPage()), (route) => false, ); }
2. Widget内异常捕获逻辑检查
查看显示"Token Expired"的Widget,确认try-catch块中是否仅展示文本,未添加跳转:
- 错误示例:
try { await UserApi.getUserInfo(); } catch (e) { if (e.toString().contains("Token Expired")) { // 仅显示异常文本 Text("Token Expired"); } }
- 修正逻辑:
try { await UserApi.getUserInfo(); } catch (e) { if (e.toString().contains("Token Expired")) { // 先清除Token再跳转 await clearLocalToken(); if (mounted) { Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage())); } } }
3. 启动页(Splash)的Token校验逻辑
检查启动页初始化时的Token校验流程,是否遗漏过期后的跳转处理:
- 关键逻辑示例:
@override void initState() { super.initState(); _checkTokenValidity(); } void _checkTokenValidity() async { String? token = await getLocalToken(); if (token == null || _isTokenExpired(token)) { // 直接跳转登录页 Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage())); } else { // 进入主页面 Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage())); } } bool _isTokenExpired(String token) { // 实现Token过期校验逻辑(解析JWT过期时间等) }
4. 上下文(Context)有效性验证
异步操作后跳转时,需确保当前Widget未被销毁:
if (mounted) { Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage())); }
优化建议
- 统一Token过期处理逻辑,建议在全局请求拦截器中集中处理,避免页面重复编写代码。
- 处理Token过期时,同步清除本地存储的无效Token,防止后续请求重复触发异常。
内容的提问来源于stack exchange,提问作者Meikisihka
相关产品推荐
相关产品推荐

