ZetCode

Dart HttpClientCredentials

最后修改于 2025 年 4 月 4 日

Dart 中的 HttpClientCredentials 类为 HTTP 请求提供了身份验证凭据。它与 HttpClient 一起用于安全通信。

HttpClientCredentials 处理基本身份验证、摘要身份验证和其他凭据类型。它是 Dart 的 dart:io 库的一部分。

基本定义

HttpClientCredentials 是一个表示 HTTP 身份验证凭据的抽象类。具体实现包括 Basic 和 Digest 凭据。

主要功能包括用户名/密码存储和身份验证方案支持。它通过 HttpClient 的身份验证 API 实现安全请求。

基本身份验证

此示例展示了使用 HttpClientCredentials 的基本 HTTP 身份验证。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  // Set up credentials
  var credentials = HttpClientBasicCredentials('user', 'pass123');
  
  // Add credentials for specific realm
  client.addCredentials(
    Uri.parse('https://example.com/secure'),
    'realm1',
    credentials
  );
  
  try {
    var request = await client.getUrl(Uri.parse('https://example.com/secure'));
    var response = await request.close();
    print('Response status: ${response.statusCode}');
  } finally {
    client.close();
  }
}

我们创建基本凭据,并将它们与特定的 URL 和域关联。当服务器提出挑战时,HttpClient 将使用这些凭据。

$ dart main.dart
Response status: 200

摘要身份验证

此示例演示了使用 HttpClientCredentials 进行摘要身份验证。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  // Set up digest credentials
  var credentials = HttpClientDigestCredentials('admin', 's3cr3t');
  
  client.addCredentials(
    Uri.parse('https://api.example.com/admin'),
    'admin-realm',
    credentials
  );
  
  try {
    var request = await client.getUrl(
      Uri.parse('https://api.example.com/admin/data')
    );
    var response = await request.close();
    print('Admin access granted: ${response.statusCode}');
  } finally {
    client.close();
  }
}

摘要身份验证比基本身份验证更安全。凭据在传输前会被哈希处理。服务器必须支持摘要身份验证。

$ dart main.dart
Admin access granted: 200

多个凭据

此示例展示了为不同域使用不同凭据。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  // User credentials for user area
  client.addCredentials(
    Uri.parse('https://example.com/user'),
    'user-realm',
    HttpClientBasicCredentials('john', 'doe123')
  );
  
  // Admin credentials for admin area
  client.addCredentials(
    Uri.parse('https://example.com/admin'),
    'admin-realm',
    HttpClientBasicCredentials('admin', 'master')
  );
  
  try {
    // Access user area
    var userRequest = await client.getUrl(
      Uri.parse('https://example.com/user/profile')
    );
    var userResponse = await userRequest.close();
    print('User status: ${userResponse.statusCode}');
    
    // Access admin area
    var adminRequest = await client.getUrl(
      Uri.parse('https://example.com/admin/dashboard')
    );
    var adminResponse = await adminRequest.close();
    print('Admin status: ${adminResponse.statusCode}');
  } finally {
    client.close();
  }
}

我们为网站的不同部分注册不同的凭据。HttpClient 会根据身份验证挑战自动选择相应的凭据。

$ dart main.dart
User status: 200
Admin status: 200

处理身份验证错误

此示例演示了身份验证失败的错误处理。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  client.addCredentials(
    Uri.parse('https://example.com/secure'),
    'test-realm',
    HttpClientBasicCredentials('wrong', 'credentials')
  );
  
  try {
    var request = await client.getUrl(
      Uri.parse('https://example.com/secure/data')
    );
    var response = await request.close();
    
    if (response.statusCode == HttpStatus.unauthorized) {
      print('Authentication failed');
    } else {
      print('Success: ${response.statusCode}');
    }
  } on SocketException catch (e) {
    print('Network error: $e');
  } finally {
    client.close();
  }
}

身份验证失败时,服务器会返回 401 Unauthorized。我们检查状态码以优雅地处理身份验证失败。

$ dart main.dart
Authentication failed

自定义身份验证方案

此示例展示了如何实现自定义身份验证凭据。

main.dart
import 'dart:io';

class ApiKeyCredentials implements HttpClientCredentials {
  final String apiKey;
  
  ApiKeyCredentials(this.apiKey);
  
  @override
  String toString() => 'API Key: $apiKey';
}

void main() async {
  var client = HttpClient();
  
  // Register custom credentials
  client.addCredentials(
    Uri.parse('https://api.example.com/v1'),
    'api-realm',
    ApiKeyCredentials('xyz123abc456')
  );
  
  // Handle authentication challenges
  client.authenticate = (url, scheme, realm) {
    print('Authenticating to $realm with $scheme');
    return true; // Attempt authentication
  };
  
  try {
    var request = await client.getUrl(
      Uri.parse('https://api.example.com/v1/data')
    );
    var response = await request.close();
    print('API response: ${response.statusCode}');
  } finally {
    client.close();
  }
}

我们创建了一个自定义凭据类用于 API 密钥身份验证。authenticate 回调允许自定义逻辑来处理身份验证挑战。

$ dart main.dart
Authenticating to api-realm with 
API response: 200

最佳实践

来源

Dart HttpClientCredentials 文档

本教程介绍了 Dart 的 HttpClientCredentials 类,并通过实际示例展示了基本和摘要身份验证、错误处理以及自定义方案。

作者

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

列出 所有 Dart 教程