dpop_flutter_dio

Dio integration for dpop_flutter - a DpopInterceptor that attaches DPoP Authorization/DPoP headers to every request and retries once on a DPoP-Nonce challenge.

dpop_flutter's core has no dependency on Dio (or any HTTP client); this adapter is the optional glue between the two.

Installation

dependencies:
  dpop_flutter: ^0.1.0
  dpop_flutter_dio: ^0.1.0

Usage

import 'package:dio/dio.dart';
import 'package:dpop_flutter/dpop_flutter.dart';
import 'package:dpop_flutter_dio/dpop_flutter_dio.dart';

final dpop = DpopClient(keyStore: SecureDpopKeyStore());
await dpop.initialize();

final dio = Dio();
dio.interceptors.add(DpopInterceptor(dpop: dpop, dio: dio, tokenProvider: myTokenProvider));

final response = await dio.get('https://api.example.com/profile');

dio is passed to the interceptor (as well as being the instance the interceptor is attached to) because a nonce-triggered retry is resent through dio.fetch(...), which needs the same Dio instance to go back through the full interceptor chain.

Nonce retry

On a 401 response carrying a DPoP-Nonce header, the interceptor stores the nonce and retries exactly once through dio.fetch(...), which naturally re-runs onRequest and picks up the fresh nonce. Requests whose body is a Stream (not safely re-sendable) are never retried. Any response (not just 401s) that carries a DPoP-Nonce header has its nonce recorded proactively for the next request to that origin.

See the main dpop_flutter README for the full DPoP overview, security model, and nonce/rotation/multi-account guidance.

Libraries

dpop_flutter_dio
Dio integration for dpop_flutter.