ZetCode

Dart HttpClientDigestCredentials

最后修改于 2025 年 4 月 4 日

Dart 中的 HttpClientDigestCredentials 类支持 HTTP 摘要身份验证。它是 Dart 的 dart:io 库的一部分。

摘要身份验证比基本身份验证更安全,因为它不会以明文形式发送密码。它使用质询-响应机制。

基本定义

HttpClientDigestCredentials 处理摘要身份验证协议。它存储用户名和密码以生成适当的响应。

主要功能包括自动质询处理、nonce 管理和正确的标头生成。它与 Dart 的 HttpClient 类配合使用。

基本摘要身份验证

此示例展示了 HttpClientDigestCredentials 的基本用法。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var credentials = HttpClientDigestCredentials('user', 'password');
  
  client.addCredentials(
    Uri.parse('http://example.com/protected'),
    'admin',
    credentials
  );
  
  try {
    var request = await client.getUrl(
      Uri.parse('http://example.com/protected')
    );
    var response = await request.close();
    print('Status: ${response.statusCode}');
  } finally {
    client.close();
  }
}

我们使用用户名和密码创建 HttpClientDigestCredentials。凭据会针对特定 URI 和领域添加到客户端。

$ dart main.dart
Status: 200

处理多个请求

此示例展示了凭据如何在多个请求中发挥作用。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var credentials = HttpClientDigestCredentials('user', 'password');
  
  client.addCredentials(
    Uri.parse('http://example.com/'),
    'admin',
    credentials
  );
  
  for (var i = 0; i < 3; i++) {
    try {
      var request = await client.getUrl(
        Uri.parse('http://example.com/protected')
      );
      var response = await request.close();
      print('Request ${i+1}: ${response.statusCode}');
    } catch (e) {
      print('Error: $e');
    }
  }
  
  client.close();
}

相同的凭据会为同一领域的多个请求重复使用。客户端会自动处理身份验证流程。

$ dart main.dart
Request 1: 200
Request 2: 200
Request 3: 200

处理身份验证失败

此示例演示了如何处理无效凭据。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var credentials = HttpClientDigestCredentials('wrong', 'credentials');
  
  client.addCredentials(
    Uri.parse('http://example.com/protected'),
    'admin',
    credentials
  );
  
  try {
    var request = await client.getUrl(
      Uri.parse('http://example.com/protected')
    );
    var response = await request.close();
    print('Status: ${response.statusCode}');
  } on HttpClientException catch (e) {
    print('Authentication failed: ${e.message}');
  } finally {
    client.close();
  }
}

当凭据无效时,会抛出 HttpClientException。我们捕获并适当地处理此异常。

$ dart main.dart
Authentication failed: HTTP authentication failed

自定义身份验证领域

此示例展示了如何指定自定义身份验证领域。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var credentials = HttpClientDigestCredentials('user', 'password');
  
  // Add credentials for specific realm
  client.addCredentials(
    Uri.parse('http://example.com/'),
    'private_area',
    credentials
  );
  
  try {
    var request = await client.getUrl(
      Uri.parse('http://example.com/secure')
    );
    var response = await request.close();
    print('Status: ${response.statusCode}');
  } finally {
    client.close();
  }
}

领域参数指定了凭据是用于哪个受保护的区域。不同的领域可以有不同的凭据。

$ dart main.dart
Status: 200

与 HttpClientRequest 一起使用

此示例展示了与 HttpClientRequest 的直接用法。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var credentials = HttpClientDigestCredentials('user', 'password');
  
  try {
    var request = await client.getUrl(
      Uri.parse('http://example.com/protected')
    );
    
    // Manually apply credentials
    var authHeaders = await credentials.getAuthHeaders(
      request.uri, 
      request.method,
      request.headers
    );
    
    authHeaders.forEach((name, value) {
      request.headers.set(name, value);
    });
    
    var response = await request.close();
    print('Status: ${response.statusCode}');
  } finally {
    client.close();
  }
}

我们手动将摘要身份验证标头应用于请求。这提供了对身份验证过程的更多控制。

$ dart main.dart
Status: 200

最佳实践

来源

Dart HttpClientDigestCredentials 文档

本教程介绍了 Dart 的 HttpClientDigestCredentials 类,并通过实际示例展示了基本用法、错误处理和高级配置。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 Dart 教程