我是 Flutter 新手,使用 http 包进行网络调用。 我的目标是刷新令牌并在访问令牌已过期时重试请求。我已经看到提到的 Dio 包,但它对我来说似乎很复杂,所以我宁愿坚持使用 http。 问题: 我想要: 在进行 API 调用之前检查访问令牌是否已过期。 如果过期,请调用刷新令牌 API 获取新令牌。 使用新令牌重试原始请求。 这是我的应用程序颤动:
此登录功能为POST accesstoken
static Future<bool> loginUser(String email, String password) async {
try {
var reqBody = {"email": email, "password": password};
var response = await http.post(
Uri.parse(login),
headers: {"Content-Type": "application/json"},
body: jsonEncode(reqBody),
);
var jsonResponse = jsonDecode(response.body);
if (jsonResponse['status']) {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('token', jsonResponse['token']);
prefs.setString('refreshToken', jsonResponse['refreshToken']);
return true;
} else {
return false;
}
} catch (error) {
throw Exception('Failed to login user: $error');
}
}
static DateTime? lastApiCallTime;
static Future<void> checkAndRefreshToken() async {
if (lastApiCallTime != null &&
DateTime.now().difference(lastApiCallTime!).inMinutes < 3) {
return;
}
lastApiCallTime = DateTime.now();
await refreshAccessToken();
}
static Future<bool> refreshAccessToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? refreshToken = prefs.getString('refreshToken');
if (refreshToken == null) {
throw Exception('No refresh token found');
}
try {
var response = await http.post(
Uri.parse(refreshTokenUrl),
headers: {"Content-Type": "application/json"},
body: jsonEncode({'refreshToken': refreshToken}),
);
if (response.statusCode == 200) {
var jsonResponse = jsonDecode(response.body);
prefs.setString('token', jsonResponse['token']);
print('New token: ${jsonResponse['token']}');
return true;
} else {
return false;
}
} catch (error) {
print('Failed to refresh token: $error');
return false;
}
}
我不确定刷新令牌后如何正确重试原始请求。
我怎样才能: 检测令牌何时过期(例如,响应 401 或类似响应)。 自动刷新令牌并使用新令牌重试请求。
你可以尝试递归。像这样的事情应该可以做到:
Future<void> recursiveAPICall() async {
final response = await http.get(Uri.parse(apiLink));
if (response.statusCode == 200) {
// do your logic
} else if (response.statusCode == 401){
// check for the accesstoken expiration and get another one
recursiveAPICall()
}
}