Flutter网络请求插件fresh_dio_next的使用
Flutter网络请求插件fresh_dio_next的使用
fresh_dio_next
是一个用于 Dart 的令牌刷新库。该包通过在发送请求之前检查令牌来扩展 fresh_dio
。
此包应该与您已经使用的 fresh_dio
兼容。通常情况下,您只需要将 Fresh.oAuth2(...)
更改为 FreshNext.oAuth2(...)
并混合您的 OAuth2Token
与 TokenProtocol
或使用 OAuth2TokenNext
类。
默认情况下,fresh_dio
会在响应码为 403 时重新发送请求,并尝试刷新令牌。而这个包首先会验证令牌,如果令牌无效,则会请求一个新的令牌。只有在那之后,fresh_dio
才会向服务器发送请求。
这种实现解决了用户发送带有 MultipartFile
的请求时,由于令牌无效而导致的错误。因为 MultipartFile
只能读取一次,第二次发送会导致错误并提示用户 “Can’t finalize a finalized MultipartFile”。发送带有无效令牌的请求会消耗互联网带宽,因此我们最好避免第一次无效令牌的请求。
示例代码
import 'package:dio/dio.dart';
import 'package:fresh/fresh.dart';
import 'package:fresh_dio/fresh_dio.dart';
import 'package:fresh_dio_next/fresh_dio_next.dart';
// 定义OAuth2Token类
class OAuth2TokenNext {
final String accessToken;
final String refreshToken;
OAuth2TokenNext({required this.accessToken, required this.refreshToken});
// 检查令牌是否有效
bool isValid() {
// 这里可以添加实际的令牌有效性检查逻辑
return accessToken.isNotEmpty;
}
}
void main() async {
// 初始化dio实例
final dio = Dio();
// 配置刷新策略
final fresh = FreshNext(
oAuth2Token: OAuth2TokenNext(
accessToken: 'your_access_token',
refreshToken: 'your_refresh_token',
),
client: dio,
tokenRefresher: () async {
// 刷新令牌的逻辑
return OAuth2TokenNext(
accessToken: 'new_access_token',
refreshToken: 'new_refresh_token',
);
},
);
// 使用dio发送请求
try {
final response = await fresh.request('https://api.example.com/data');
print(response.data);
} catch (e) {
print(e);
}
}
详细步骤
- 引入依赖:
在
pubspec.yaml
文件中添加fresh_dio_next
依赖:dependencies: dio: ^4.0.0 fresh: ^1.0.0 fresh_dio: ^1.0.0 fresh_dio_next: ^1.0.0
更多关于Flutter网络请求插件fresh_dio_next的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求插件fresh_dio_next的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
fresh_dio_next
是一个基于 dio
的 Flutter 网络请求插件,它提供了自动刷新 Token、请求重试、缓存等功能,特别适合处理需要认证的 API 请求。下面是如何使用 fresh_dio_next
的基本步骤。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 fresh_dio_next
和 dio
的依赖:
dependencies:
flutter:
sdk: flutter
dio: ^5.0.0
fresh_dio_next: ^1.0.0
然后运行 flutter pub get
来安装依赖。
2. 创建 Fresh
实例
Fresh
是 fresh_dio_next
的核心类,用于管理认证 Token 和请求的刷新逻辑。
import 'package:dio/dio.dart';
import 'package:fresh_dio_next/fresh_dio_next.dart';
final dio = Dio();
final fresh = Fresh<AuthToken>(
tokenHeader: (token) {
return {'Authorization': '${token.tokenType} ${token.accessToken}'};
},
refreshToken: (token, dio) async {
// 这里实现 Token 刷新逻辑
final response = await dio.post('/refresh_token', data: {
'refresh_token': token.refreshToken,
});
return AuthToken(
accessToken: response.data['access_token'],
refreshToken: response.data['refresh_token'],
tokenType: response.data['token_type'],
);
},
shouldRefresh: (response) {
// 这里定义何时需要刷新 Token,例如当返回 401 状态码时
return response.statusCode == 401;
},
);
3. 配置 Dio
实例
将 Fresh
实例与 Dio
实例关联:
dio.interceptors.add(fresh);
4. 定义 AuthToken
类
AuthToken
是一个简单的数据类,用于存储 Token 信息:
class AuthToken {
final String accessToken;
final String refreshToken;
final String tokenType;
AuthToken({
required this.accessToken,
required this.refreshToken,
required this.tokenType,
});
}
5. 发起请求
现在你可以使用 Dio
发起请求,Fresh
会自动处理 Token 的刷新和请求的重试:
Future<void> fetchData() async {
try {
final response = await dio.get('/api/data');
print(response.data);
} catch (e) {
print('Error: $e');
}
}
6. 设置初始 Token
如果你已经有初始的 Token,可以将其设置到 Fresh
实例中:
fresh.setToken(AuthToken(
accessToken: 'initial_access_token',
refreshToken: 'initial_refresh_token',
tokenType: 'Bearer',
));
7. 处理 Token 过期
当 Token 过期时,Fresh
会自动调用 refreshToken
方法来获取新的 Token,并重新发起失败的请求。
8. 其他配置
Fresh
还提供了其他一些配置选项,例如自定义 Token 存储、请求重试次数等。你可以根据需要进行配置。
final fresh = Fresh<AuthToken>(
tokenStorage: InMemoryTokenStorage<AuthToken>(),
maxRefreshAttempts: 3,
// 其他配置
);
9. 示例代码
以下是一个完整的示例代码:
import 'package:dio/dio.dart';
import 'package:fresh_dio_next/fresh_dio_next.dart';
class AuthToken {
final String accessToken;
final String refreshToken;
final String tokenType;
AuthToken({
required this.accessToken,
required this.refreshToken,
required this.tokenType,
});
}
void main() async {
final dio = Dio();
final fresh = Fresh<AuthToken>(
tokenHeader: (token) {
return {'Authorization': '${token.tokenType} ${token.accessToken}'};
},
refreshToken: (token, dio) async {
final response = await dio.post('/refresh_token', data: {
'refresh_token': token.refreshToken,
});
return AuthToken(
accessToken: response.data['access_token'],
refreshToken: response.data['refresh_token'],
tokenType: response.data['token_type'],
);
},
shouldRefresh: (response) {
return response.statusCode == 401;
},
);
dio.interceptors.add(fresh);
fresh.setToken(AuthToken(
accessToken: 'initial_access_token',
refreshToken: 'initial_refresh_token',
tokenType: 'Bearer',
));
try {
final response = await dio.get('/api/data');
print(response.data);
} catch (e) {
print('Error: $e');
}
}