美文网首页
2023-02-16 flutter对http组件封装进行HTT

2023-02-16 flutter对http组件封装进行HTT

作者: 我是小胡胡123 | 来源:发表于2023-02-16 10:41 被阅读0次

flutter对http组件的网络请求对象的封装,
请求头header中添加令牌参数 authorization

/// This client authenticates requests by injecting `Authentication` header to
/// requests.
///
/// Requests to URLs not under [serverBaseUrl] will not be authenticated.
class _AuthenticatedClient extends http.BaseClient {
  /// Constructs Http client wrapper that injects `authorization` header to
  /// requests and handles authentication errors.
  ///
  /// [_credential] might be `null`. In that case `authorization` header will not
  /// be injected to requests.
  _AuthenticatedClient(this._inner, this._credential);

  final http.BaseClient _inner;

  /// Authentication scheme that could be used for authenticating requests.
  final Credential? _credential;

  /// Detected that [_credential] are invalid, happens when server responds 401.
  bool _detectInvalidCredentials = false;

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) async {
    // Let's last time make sure that, we're allowed to use credential for this
    // request.
    //
    // This check ensures that this client will only authenticate requests sent
    // to given serverBaseUrl. Otherwise credential leaks might ocurr when
    // archive_url hosted on 3rd party server that should not receive
    // credentials of the first party.
    if (_credential != null &&
        _credential!.canAuthenticate(request.url.toString())) {
      request.headers[HttpHeaders.authorizationHeader] =
          await _credential!.getAuthorizationHeaderValue();
    }

    final response = await _inner.send(request);
    if (response.statusCode == 401) {
      _detectInvalidCredentials = true;
    }
    if (response.statusCode == 401 || response.statusCode == 403) {
      _throwAuthException(response);
    }
    return response;
  }

  /// Throws [AuthenticationException] that includes response status code and
  /// message parsed from WWW-Authenticate header usign
  /// [RFC 7235 section 4.1][RFC] specifications.
  ///
  /// [RFC]: https://datatracker.ietf.org/doc/html/rfc7235#section-4.1
  void _throwAuthException(http.BaseResponse response) {
    String? serverMessage;
    if (response.headers.containsKey(HttpHeaders.wwwAuthenticateHeader)) {
      try {
        final header = response.headers[HttpHeaders.wwwAuthenticateHeader]!;
        final challenge =
            AuthenticationChallenge.parseHeader(header).firstWhereOrNull(
          (challenge) =>
              challenge.scheme == 'bearer' &&
              challenge.parameters['realm'] == 'pub' &&
              challenge.parameters['message'] != null,
        );
        if (challenge != null) {
          serverMessage = challenge.parameters['message'];
        }
      } on FormatException {
        // Ignore errors might be caused when parsing invalid header values
      }
    }
    if (serverMessage != null) {
      // Only allow printable ASCII, map anything else to whitespace, take
      // at-most 1024 characters.
      serverMessage = String.fromCharCodes(
        serverMessage.runes.map((r) => 32 <= r && r <= 127 ? r : 32).take(1024),
      );
    }
    throw AuthenticationException(response.statusCode, serverMessage);
  }

  @override
  void close() => _inner.close();
}

这段代码定义了一个名为 _AuthenticatedClient 的 Dart 类,它用于包装 http.BaseClient 的实例,以便对 HTTP 请求进行身份验证。它检查给定请求的 URL 是否在指定的服务器基础 URL 下,如果是,则注入一个包含从提供的 Credential 对象获取的凭据的 Authorization 头。如果包装的 http.BaseClient 发送状态码为 401 或 403 的响应,则该类将抛出一个包含状态码和从响应的 WWW-Authenticate 头解析出的消息的 AuthenticationException。

以下是该类的关键组件:

http.BaseClient _inner:这是 _AuthenticatedClient 包装的 http.BaseClient 的实例。它用于发送 HTTP 请求并接收响应。

Credential? _credential:这是一个可选的 Credential 对象,用于存储身份验证请求所需的信息,例如访问令牌或 API 密钥。如果未提供此对象或请求的 URL 不在指定的服务器基础 URL 下,则 _AuthenticatedClient 将不会向请求中注入 Authorization 头。

Future<http.StreamedResponse> send(http.BaseRequest request):该方法使用包装的 _inner 客户端发送 HTTP 请求。在发送请求之前,它检查 _credential 是否可以对请求的 URL 进行身份验证,如果可以,则向请求中注入 Authorization 头。在接收到响应后,它检查响应的状态码是否为 401 或 403,如果是,则抛出一个 AuthenticationException。

_throwAuthException(http.BaseResponse response):该方法抛出一个包含状态码和从响应的 WWW-Authenticate 头解析出的消息的 AuthenticationException。它使用 AuthenticationChallenge 类来解析头,并从 bearer 方案的 realm 和 message 参数中提取消息。

相关文章

  • flutter封装AppBar

    flutter封装AppBar 最近做flutter项目,为了更简洁,封装了AppBar组件,不过不是自定义组件哈...

  • vue左侧菜单递归组件--基于 iview dropdown组

    基于 iview dropdown 组件,$http 用 axios 进行了封装 SideBar.vue (递归...

  • 2018-03-27

    组件(一) 什么是组件 组件可以扩展 HTML 元素,封装可重用的代码。 组件是对原始HTML进行一层封装,来拓展...

  • Vue使用http服务

    Vue对http的请求服务进行了单独的组件封装,我们就可以愉快的在js或者vue中使用vue-resource进行...

  • React-2:组件、

    组件 web组件就是对web中的数据、结构、方法等进行封装,复用,与JavaScript中功能函数封装类似...

  • Flutter 对组件进行裁剪

    Flutter 中提供了一些剪裁函数,用于对组件进行剪裁。 剪裁Widget作用ClipOval子组件为正方形时剪...

  • iOS开发中的组件化开篇

    什么是组件化? 它是一种App架构思路,对代码进行封装,封装成组件,组件可以单独使用。项目中使用组件包括基础组件(...

  • 对input进行简单封装组件

  • react hoc

    高阶函数对组件的封装,譬如多个组件大部分相同,只是需要局部变化,可通过高阶函数来进行封装处理。

  • Flutter了解之入门篇10-1(可滚动组件)

    Flutter官方并没有对Widget进行分类,对其分类主要是为了对Widget进行功能区分。 当组件超过显示窗口...

网友评论

      本文标题:2023-02-16 flutter对http组件封装进行HTT

      本文链接:https://www.haomeiwen.com/subject/pvxukdtx.html