Dart HttpClientDigestCredentials
last modified October 18, 2026
The HttpClientDigestCredentials class in Dart provides support for
HTTP digest authentication. It's part of Dart's dart:io library.
Digest authentication is more secure than basic authentication as it doesn't send passwords in clear text. It uses a challenge-response mechanism.
Basic Definition
HttpClientDigestCredentials handles the digest authentication
protocol. It stores username and password for generating proper responses.
Key features include automatic challenge handling, nonce management, and proper header generation. It works with Dart's HttpClient class.
Basic Digest Authentication
This example shows basic usage of HttpClientDigestCredentials.
import 'dart:io';
void main() async {
var client = HttpClient();
var url = Uri.parse('https://httpbin.org/digest-auth/auth/user/password');
var credentials = HttpClientDigestCredentials('user', 'password');
client.addCredentials(
url,
'me@kennethreitz.com',
credentials
);
try {
var request = await client.getUrl(url);
var response = await request.close();
await response.drain<void>();
print('Status: ${response.statusCode}');
} finally {
client.close();
}
}
We create HttpClientDigestCredentials with username and password. The credentials are added to the client for a specific URI and realm. The realm must match the realm sent by the server in its authentication challenge.
$ dart main.dart Status: 200
Handling Multiple Requests
This example shows how credentials work across multiple requests.
import 'dart:io';
void main() async {
var client = HttpClient();
var url = Uri.parse('https://httpbin.org/digest-auth/auth/user/password');
var credentials = HttpClientDigestCredentials('user', 'password');
client.addCredentials(
url,
'me@kennethreitz.com',
credentials
);
for (var i = 0; i < 3; i++) {
try {
var request = await client.getUrl(url);
var response = await request.close();
await response.drain<void>();
print('Request ${i+1}: ${response.statusCode}');
} catch (e) {
print('Error: $e');
}
}
client.close();
}
The same credentials are reused for multiple requests to the same realm. The client handles the authentication flow automatically.
$ dart main.dart Request 1: 200 Request 2: 200 Request 3: 200
Handling Authentication Failure
This example demonstrates handling invalid credentials.
import 'dart:io';
void main() async {
var client = HttpClient();
var url = Uri.parse('https://httpbin.org/digest-auth/auth/user/password');
var credentials = HttpClientDigestCredentials('wrong', 'credentials');
client.addCredentials(
url,
'me@kennethreitz.com',
credentials
);
try {
var request = await client.getUrl(url);
var response = await request.close();
await response.drain<void>();
if (response.statusCode == HttpStatus.unauthorized) {
print('Authentication failed: ${response.statusCode}');
} else {
print('Status: ${response.statusCode}');
}
} finally {
client.close();
}
}
When credentials are invalid, the server responds with 401 Unauthorized. We check the status code instead of expecting an exception.
$ dart main.dart Authentication failed: 401
Matching the Authentication Realm
This example shows how to use the realm expected by the server.
import 'dart:io';
void main() async {
var client = HttpClient();
var url = Uri.parse('https://httpbin.org/digest-auth/auth/admin/secret');
var credentials = HttpClientDigestCredentials('admin', 'secret');
// The realm is part of the digest hash, so it must match the server.
client.addCredentials(
url,
'me@kennethreitz.com',
credentials
);
try {
var request = await client.getUrl(url);
var response = await request.close();
await response.drain<void>();
print('Status: ${response.statusCode}');
} finally {
client.close();
}
}
The realm parameter is used when computing the digest response, so it must match the realm sent by the server. The URL selects the protected resource; different paths can require different credentials.
$ dart main.dart Status: 200
Using with HttpClientRequest
This example shows how credentials registered on the client apply to a request created with HttpClientRequest.
import 'dart:io';
void main() async {
var client = HttpClient();
var url = Uri.parse('https://httpbin.org/digest-auth/auth/user/password');
var credentials = HttpClientDigestCredentials('user', 'password');
client.addCredentials(url, 'me@kennethreitz.com', credentials);
try {
var request = await client.getUrl(url);
var response = await request.close();
await response.drain<void>();
print('Status: ${response.statusCode}');
} finally {
client.close();
}
}
Digest headers cannot be computed until the server supplies a nonce, so credentials are registered on the client. The client handles the challenge and retries the request with the generated Authorization header.
$ dart main.dart Status: 200
Best Practices
- Secure storage: Never hardcode credentials in source code
- Error handling: Always handle authentication failures
- Reuse clients: Reuse HttpClient instances when possible
- Realm matching: Ensure realm matches server configuration
Source
Dart HttpClientDigestCredentials Documentation
This tutorial covered Dart's HttpClientDigestCredentials class with practical examples showing basic usage, error handling, and advanced configuration.
Author
List all Dart tutorials.