jasny/http-digest

PSR-7 客户端和服务器中间件,用于创建和验证 HTTP Digest 标头,如 RFC 3230 所述

v1.2.1 2019-06-03 17:31 UTC

This package is auto-updated.

Last update: 2024-09-16 08:39:25 UTC


README

Build Status Scrutinizer Code Quality Code Coverage Packagist Stable Version Packagist License

PSR-7 客户端和服务器中间件,用于创建和验证 HTTP Digest 标头,如 RFC 3230 所述。支持 MD5、SHA、SHA-256 和 SHA-512(《RFC 5843》)。

Digest 标头包含体内容的哈希值。

Digest: SHA=thvDyvhfIqlvFe+A9MYgxAfm1q5=

Want-Digest 消息标头字段表示发送者希望接收与 Request-URI 相关的消息的实例摘要。

Want-Digest: MD5;q=0.3, SHA;q=1

安装

composer require jasny/http-digest

用法

创建 HttpDigest 服务以创建和验证摘要。给服务器指定支持的算法优先级。此值应类似于 Want-Digest 标头中的值。

use Jasny\HttpDigest\HttpDigest;

$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);

优先级也可以指定为字符串。

$service = new HttpDigest("MD5;q=0.3, SHA;q=1");

可以创建用于内容协商的服务,并将其传递给构造函数以进行适当的依赖注入。

use Jasny\HttpDigest\HttpDigest;

$negotiator = new DigestNegotiator();
$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"], $negotiator);

创建摘要

您可以使用此服务为内容创建摘要。

$digest = $service->create($body);

验证摘要

您可以使用此服务来验证摘要。

$service->verify($body, $digest);

如果摘要不匹配或算法不受支持,则会抛出 HttpDigestException

优先级和 Want-Digest 标头

您可以使用 withPriorities() 更改优先级。这将创建服务的新副本。

$newService = $service->withPriorities(["MD5;q=0.3", "SHA;q=0.5", "SHA-256;q=1"]);

要获取配置的优先级,请使用 getPriorities()getWantDigest() 函数以字符串形式返回优先级,格式与 Wanted-Digest 所期望的格式相同。

$priorities = $service->getPriorities();
$header = $service->getWantDigest();

服务器中间件

可以使用服务器中间件来验证 PSR-7 请求的摘要。

当使用中间件时,包含体(如 POSTGET 请求)的请求必须包含 Digest 标头。如果缺少 Digest 标头、无效或不满足要求,则中间件将返回包含 With-Digest 标头的 400 Bad Request 响应,并且处理程序不会被调用。

单次通过中间件(PSR-15)

中间件实现了 PSR-15 的 MiddlewareInterface。由于 PSR 标准被许多新库支持,例如 Zend Stratigility

您必须提供 PSR-17 响应工厂,以创建对具有无效签名的请求的 400 Bad Request 响应。

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);

双次通过中间件

许多 PHP 库支持双次通过中间件。这些是具有以下签名的可调用对象;

fn(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface

要使用 asDoublePass() 方法获取用于 Jasny RouterRelay 的回调,请使用 asDoublePass() 方法。

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);

客户端中间件

客户端中间件可以用于签名由 PSR-7 兼容的 HTTP 客户端(如 GuzzleHTTPlug)发送的请求。

use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ClientMiddleware;

$service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
$middleware = new ClientMiddleware($service);

双次通过中间件

客户端中间件可以由任何支持双次通过中间件客户端使用。此类中间件是可调用对象,具有以下签名;

fn(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface

大多数 HTTP 客户端不支持双次通过中间件,而是使用单次通过。但是,更通用的 PSR-7 中间件库,如 Relay,支持双次通过。

use Relay\RelayBuilder;

$relayBuilder = new RelayBuilder($resolver);
$relay = $relayBuilder->newInstance([
    $middleware->asDoublePass(),
]);

$response = $relay($request, $baseResponse);

客户端中间件不符合PSR-15(单遍)规范,因为该规范仅适用于服务器请求。

Guzzle

Guzzle 是最流行的PHP HTTP客户端。中间件提供了一个 forGuzzle() 方法,该方法创建一个回调函数,可以用作Guzzle中间件。

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

HTTPlug 是PHP-HTTP的HTTP客户端。它允许您编写需要HTTP客户端且不绑定到特定实现的可重用库和应用程序。

中间件的 forHttplug() 方法创建一个对象,该对象可以用作HTTPlug插件。

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(),
    ]
);