面试题答案
一键面试- 安装Dio插件:
在
pubspec.yaml
文件中添加dio
依赖:
然后运行dependencies: dio: ^[latest_version]
flutter pub get
。 - 创建认证拦截器:
首先定义一个认证拦截器类,它继承自
InterceptorsWrapper
。class AuthInterceptor extends InterceptorsWrapper { // 存储认证信息,如token String? token; // 标记是否正在刷新token bool isRefreshing = false; // 用于等待刷新token完成的队列 final List<RequestOptions> requestQueue = []; @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { if (token!= null) { options.headers['Authorization'] = 'Bearer $token'; } handler.next(options); } @override void onResponse(Response response, ResponseInterceptorHandler handler) { // 如果认证未过期,直接返回响应 if (response.statusCode == 200) { handler.next(response); } else { // 处理认证过期等其他错误情况 handleError(response, handler); } } @override void onError(DioError err, ErrorInterceptorHandler handler) { if (err.response?.statusCode == 401) { // 认证过期,处理认证过期逻辑 handleError(err.response, handler); } else { handler.next(err); } } void handleError(Response? response, [ErrorInterceptorHandler? handler]) { if (!isRefreshing) { isRefreshing = true; // 刷新token的逻辑,这里假设存在一个refreshToken函数 refreshToken().then((newToken) { token = newToken; isRefreshing = false; requestQueue.forEach((req) => _retryRequest(req, handler)); requestQueue.clear(); }).catchError((error) { isRefreshing = false; // 刷新token失败的处理 if (handler!= null) { handler.reject(DioError( response: response, error: error, type: DioErrorType.other, )); } }); } if (handler!= null) { requestQueue.add(response?.requestOptions?? RequestOptions()); } } Future<String> refreshToken() async { // 实际刷新token的逻辑,如调用刷新API // 这里假设返回一个新的token字符串 return 'new_token'; } void _retryRequest(RequestOptions options, ErrorInterceptorHandler? handler) { options.headers['Authorization'] = 'Bearer $token'; Dio dio = Dio(); dio.request<dynamic>(options.path, options: options).then((response) { if (handler!= null) { handler.resolve(response); } }).catchError((error) { if (handler!= null) { handler.reject(error); } }); } }
- 添加拦截器到Dio实例:
在创建Dio实例时添加认证拦截器:
Dio dio = Dio(); dio.interceptors.add(AuthInterceptor());
通过上述步骤,使用Dio的拦截器可以统一管理不同API请求的认证头信息,并且在认证信息过期时,能够自动刷新并重新发起原请求,同时也处理了多个请求并发时的情况。