Flutter使用Dio请求API报401错误无法展示接口数据问题求助
问题错误点梳理
- 请求头设置顺序错误(直接导致401):
getUserCards方法中你先执行了await dio.get(get_cards)发起请求,之后才设置Authorization请求头,请求发送时根本没有携带认证信息,所以直接返回401未授权。 - token值未正确赋值:全局
token初始硬编码为无效的字符串"token",登录接口返回的真实token你没有赋值给这个全局变量,反而在登录请求发送前就把无效的"token"存入了本地存储,所有后续请求带的都是无效token。 - 刷新token逻辑完全不符合规范:
- 401触发刷新逻辑时,刷新请求未携带合法的refresh_token参数,且你把
Content-Type、refresh_token字段都错误拼接进了Authorization请求头中,不符合JWT认证的格式要求 - 错误将
FlutterSecureStorage实例直接赋值为token字符串,导致后续无法再通过该实例读写本地存储数据 - 递归调用
loginUser时硬传了"username"、"password"字符串,而非用户输入的真实账号密码,递归登录也必然失败
- 401触发刷新逻辑时,刷新请求未携带合法的refresh_token参数,且你把
- 接口返回值和UI层逻辑不匹配:
getUserCards返回的是单个字符串值,但UI层的FutureBuilder中将返回值当做数组调用.length、通过[index]取值,就算接口请求成功也会抛出类型异常。
核心逻辑修正示例
// 修正后的getUserCards核心逻辑 Future getUserCards() async { try { // 先设置请求头再发起请求 dio.options.headers["Authorization"] = "Bearer ${token}"; dio.options.headers['Content-Type'] = "application/json"; var get_cards = "https://example/api/cards"; Response resp = await dio.get(get_cards); // 这里根据接口实际返回结构调整返回值,要返回数组匹配UI层 return resp.data["list"]; } catch (e) { print(e); rethrow; } }
// 修正后的登录核心逻辑 Future loginUser(String username, String password) async { var storage = FlutterSecureStorage(); var login = "https://example/users/login/"; final data = {"username": username, "password": password}; dio.options.headers['Content-Type'] = "application/json"; Response response = await dio.post(login, data: data); if (response.statusCode == 200) { // 先拿返回的真实token赋值 token = response.data["token"]; refresh_token = response.data["refresh_token"]; // 存到本地 await storage.write(key: 'JWT', value: token); await storage.write(key: 'refreshToken', value: refresh_token); // 设置全局请求头 dio.options.headers["Authorization"] = "Bearer ${token}"; Get.to(CardScreen()); return response.data; } else if (response.statusCode == 401) { // 刷新token逻辑 var refreshResp = await dio.post( "https://example/api/cards/refresh/", data: {"refresh_token": refresh_token}, ); if (refreshResp.statusCode == 200) { token = refreshResp.data["token"]; refresh_token = refreshResp.data["refresh_token"]; await storage.write(key: 'JWT', value: token); dio.options.headers["Authorization"] = "Bearer ${token}"; // 传入真实账号密码重新发起登录 return loginUser(username, password); } return null; } else { return null; } }
内容的提问来源于stack exchange,提问作者Mc Ride
相关产品推荐
相关产品推荐

