0
点赞
收藏
分享

微信扫一扫

flutter Dio插件的使用 (十三)

月白色的大狒 2022-04-02 阅读 40
flutter

Dio对象在App请求中一般在单例对象中使用,用来与后端进行普通的网络请求,如POST\GET等。Dio支持使用拦截器对所有的请求进行拦截,从而进行特殊处理,如增加token参数、请求和响应日志记录等。参考代码片段:

引用头文件:

import 'package:dio/dio.dart';
import 'interceptor/http_interceptor.dart';

在类的构造中,添加自定义的拦截器:

class ThingsboardClient {
        ///......
        
  factory ThingsboardClient() {
    var dio = Dio();
    dio.options.baseUrl = apiEndpoint;
    dio.interceptors.clear();
    dio.interceptors.add(HttpInterceptor());
    ///......
  }

自定义的拦截器,拦截所有的API类型的请求,并添加token:

class HttpInterceptor extends Interceptor {
  static const String _authScheme = 'Bearer ';
  static const _authHeaderName = 'X-Authorization';
  ///...
  
  @override
  Future onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    if (options.path.startsWith('/api/')) {
      var config = _getInterceptorConfig(options);
      var isLoading = !_isInternalUrlPrefix(options.path);
      if (!config.isRetry) {
        _updateLoadingState(config, isLoading);
      }
       ///路径是否需要token
      if (_isTokenBasedAuthEntryPoint(options.path)) {
        ///token是否有效
        if (_tbClient.getJwtToken() == null &&
            !_tbClient.refreshTokenPending()) {
          return _handleRequestError(
              options, handler, ThingsboardError(message: 'Unauthorized!'));
        } else if (!_tbClient.isJwtTokenValid()) {
            ///token不可用,返回错误,刷新token后,重新提交请求
            return _handleRequestError(
              options, handler, ThingsboardError(refreshTokenPending: true));
        } else {
              ///处理请求,添加token等头信息
          return _jwtIntercept(options, handler);
        }
      } else {
        return _handleRequest(options, handler);
      }
    } else {
      return handler.next(options);
    }
  }

  ///需要启用token的路径
  bool _isTokenBasedAuthEntryPoint(String url) {
    return url.startsWith('/api/') &&
        !url.startsWith(Constants.entryPoints['login']!) &&
        !url.startsWith(Constants.entryPoints['tokenRefresh']!) &&
        !url.startsWith(Constants.entryPoints['nonTokenBased']!);
  }


  bool _updateAuthorizationHeader(RequestOptions options) {
    var jwtToken = _tbClient.getJwtToken();
    if (jwtToken != null) {
      options.headers[_authHeaderName] = _authScheme + jwtToken;
      return true;
    } else {
      return false;
    }
  }

  Future _jwtIntercept(
      RequestOptions options, RequestInterceptorHandler handler) async {
    ///更新头授权token等信息
    if (_updateAuthorizationHeader(options)) {
      return _handleRequest(options, handler);
    } else {
      return _handleRequestError(options, handler,
          ThingsboardError(message: 'Could not get JWT token from store.'));
    }
  }

   ///...
}
举报

相关推荐

0 条评论