PSR-7 middleware for HTTP Digest header (RFC 3230)
PSR-7 client and server middleware for HTTP Digest header creation and validation as described in
RFC 3230. Supports MD5, SHA, SHA-256 and SHA-512
(RFC 5843).
The Digest
header contains a hash of the body.
Digest: SHA=thvDyvhfIqlvFe+A9MYgxAfm1q5=
The Want-Digest message header field indicates the sender’s desire to receive an instance digest on messages associated
with the Request-URI.
Want-Digest: MD5;q=0.3, SHA;q=1
composer require jasny/http-digest
Create the HttpDigest
service to create and verify digests. Give the server priorities for supported algorithms. This
value should be similar to those in the Want-Digest
header.
use Jasny\HttpDigest\HttpDigest;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
The priorities may also be specified as string.
$service = new HttpDigest("MD5;q=0.3, SHA;q=1");
The service for content negotiating may be created and passes in the constructor for proper DI.
use Jasny\HttpDigest\HttpDigest;
$negotiator = new DigestNegotiator();
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"], $negotiator);
You can use the service to create a digest for content.
$digest = $service->create($body);
You can use the service to verify the digest.
$service->verify($body, $digest);
If the digest doesn’t match or if the algorithm is unsupported, a HttpDigestException
is thrown.
Want-Digest
headerYou can change the priorities using withPriorities()
. This will create a new copy of the service.
$newService = $service->withPriorities(["MD5;q=0.3", "SHA;q=0.5", "SHA-256;q=1"]);
To get the configured priorities use getPriorities()
. The getWantDigest()
function returns the priorities in as a
string in the format expected for Wanted-Digest
.
$priorities = $service->getPriorities();
$header = $service->getWantDigest();
Server middleware can be used to verify the digest of PSR-7 requests.
When the middleware is used, requests with a body (like POST
or GET
requests) must contain a Digest
header.
If the Digest
header is missing, invalid or doesn’t meet the requirements, the middleware will return a400 Bad Request
response with a With-Digest
header and the handler will not be called.
The middleware implements the PSR-15 MiddlewareInterface
. As PSR standard many new libraries support this type of
middleware, for example Zend Stratigility.
You’re required to supply a PSR-17 response factory,
to create a 400 Bad Request
response for requests with invalid signatures.
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ServerMiddleware;
use Zend\Stratigility\MiddlewarePipe;
use Zend\Diactoros\ResponseFactory;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$responseFactory = new ResponseFactory();
$middleware = new ServerMiddleware($service, $responseFactory);
$app = new MiddlewarePipe();
$app->pipe($middleware);
Many PHP libraries support double pass middleware. These are callables with the following signature;
fn(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
To get a callback to be used by libraries as Jasny Router and
Relay, use the asDoublePass()
method.
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ServerMiddleware;
use Relay\RelayBuilder;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$middleware = new ServerMiddleware($service);
$relayBuilder = new RelayBuilder($resolver);
$relay = $relayBuilder->newInstance([
$middleware->asDoublePass(),
]);
$response = $relay($request, $baseResponse);
Client middleware can be used to sign requests send by PSR-7 compatible HTTP clients like
Guzzle and HTTPlug.
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ClientMiddleware;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$middleware = new ClientMiddleware($service);
The client middleware can be used by any client that does support double pass middleware. Such middleware are callables
with the following signature;
fn(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
Most HTTP clients do not support double pass middleware, but a type of single pass instead. However more general
purpose PSR-7 middleware libraries, like Relay, do support double pass.
use Relay\RelayBuilder;
$relayBuilder = new RelayBuilder($resolver);
$relay = $relayBuilder->newInstance([
$middleware->asDoublePass(),
]);
$response = $relay($request, $baseResponse);
The client middleware does not conform to PSR-15 (single pass) as that is intended for server requests only.
Guzzle is the most popular HTTP Client for PHP. The middleware has a forGuzzle()
method
that creates a callback which can be used as Guzzle middleware.
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Client;
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ClientMiddleware;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$middleware = new ClientMiddleware($service);
$stack = new HandlerStack();
$stack->push($middleware->forGuzzle());
$client = new Client(['handler' => $stack]);
HTTPlug is the HTTP client of PHP-HTTP. It allows you
to write reusable libraries and applications that need an HTTP client without binding to a specific implementation.
The forHttplug()
method for the middleware creates an object that can be used as HTTPlug plugin.
use Http\Discovery\HttpClientDiscovery;
use Http\Client\Common\PluginClient;
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ClientMiddleware;
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$middleware = new ClientMiddleware($service);
$pluginClient = new PluginClient(
HttpClientDiscovery::find(),
[
$middleware->forHttplug(),
]
);