digest_auth 1.0.1
digest_auth: ^1.0.1 copied to clipboard
HTTP Digest Authentication for Monero's JSON-RPC API.
example/digest_auth_example.dart
import 'dart:convert';
import 'package:digest_auth/digest_auth.dart';
import 'package:http/http.dart' as http;
void main() async {
final daemonRpc = DaemonRpc(
'http://localhost:18081/json_rpc', // Replace with your Monero daemon URL.
username: 'user', // Replace with your username.
password: 'password', // Replace with your password.
);
try {
final result = await daemonRpc.call('get_info', {});
print('get_info response:');
print(result);
} catch (e) {
print('Error: $e');
}
}
// Copied from the monero_rpc package in order to avoid recursive dependencies.
class DaemonRpc {
final String rpcUrl;
final String username;
final String password;
DaemonRpc(this.rpcUrl, {required this.username, required this.password});
/// Perform a JSON-RPC call with Digest Authentication.
Future<Map<String, dynamic>> call(
String method, Map<String, dynamic> params) async {
final http.Client client = http.Client();
final DigestAuth digestAuth = DigestAuth(username, password);
// Initial request to get the `WWW-Authenticate` header.
final initialResponse = await client.post(
Uri.parse(rpcUrl),
headers: {
'Content-Type': 'application/json',
},
body: jsonEncode({
'jsonrpc': '2.0',
'id': '0',
'method': method,
'params': params,
}),
);
if (initialResponse.statusCode != 401 ||
!initialResponse.headers.containsKey('www-authenticate')) {
throw Exception('Unexpected response: ${initialResponse.body}');
}
// Extract Digest details from `WWW-Authenticate` header.
final String authInfo = initialResponse.headers['www-authenticate']!;
digestAuth.initFromAuthorizationHeader(authInfo);
// Create Authorization header for the second request.
String uri = Uri.parse(rpcUrl).path;
String authHeader = digestAuth.getAuthString('POST', uri);
// Make the authenticated request.
final authenticatedResponse = await client.post(
Uri.parse(rpcUrl),
headers: {
'Content-Type': 'application/json',
'Authorization': authHeader,
},
body: jsonEncode({
'jsonrpc': '2.0',
'id': '0',
'method': method,
'params': params,
}),
);
if (authenticatedResponse.statusCode != 200) {
throw Exception('RPC call failed: ${authenticatedResponse.body}');
}
final Map<String, dynamic> result = jsonDecode(authenticatedResponse.body);
if (result['error'] != null) {
throw Exception('RPC Error: ${result['error']}');
}
return result['result'];
}
}