Flutter网络请求插件fresh_dio_next的使用

Flutter网络请求插件fresh_dio_next的使用

fresh_dio_next 是一个用于 Dart 的令牌刷新库。该包通过在发送请求之前检查令牌来扩展 fresh_dio

此包应该与您已经使用的 fresh_dio 兼容。通常情况下,您只需要将 Fresh.oAuth2(...) 更改为 FreshNext.oAuth2(...) 并混合您的 OAuth2TokenTokenProtocol 或使用 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);
  }
}

详细步骤

  1. 引入依赖: 在 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

1 回复

更多关于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_nextdio 的依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.0.0
  fresh_dio_next: ^1.0.0

然后运行 flutter pub get 来安装依赖。

2. 创建 Fresh 实例

Freshfresh_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');
  }
}
回到顶部