facile-it/php-oauth2-http-client

OpenID/OAuth2 授权支持的 HTTPlug 插件

dev-master 2020-08-04 13:14 UTC

This package is auto-updated.

Last update: 2024-09-04 22:35:36 UTC


README

OAuth2 授权的 HTTPlug 插件。

Latest Stable Version Total Downloads License Code Coverage Build Status Scrutinizer Code Quality

此软件包允许您使用兼容的 PSR-18 HTTP 客户端,并在请求外部受保护资源时处理 OAuth2 授权。

此软件包基于 facile-it/php-openid-client 进行身份验证。您需要了解如何使用它,特别是创建客户端。

安装

composer require facile-it/php-oauth2-http-client

HTTPlug 插件

此库提供了一个 HTTPlug 插件来处理授权,因此您需要创建其实例。

客户端将用于身份验证和对令牌端点的请求。

当资源服务器以 401403 状态码响应时,此插件会尝试进行授权请求以获取 Bearer 访问令牌,并使用填充的 Authorization 标头重试请求。默认情况下,在执行真实请求之前,总是先进行获取访问令牌的授权请求。

// facile-it/php-openid-client dependencies
use Facile\OpenIDClient\Service\AuthorizationService;
use Facile\OpenIDClient\Client\ClientInterface;
use Facile\OAuth2\HttpClient\OAuth2Plugin;

// create an OIDC/OAuth2 client and the AuthorizationService from facile-it/php-openid-client
/** @var AuthorizationService $authorizationService */
/** @var ClientInterface $client */

$oauth2Plugin = new OAuth2Plugin($authorizationService, $client);

现在您可以将插件注入到您的客户端。

使用 PSR-18 HTTP 客户端的使用方法

要使用 PSR-18 客户端,您可以使用之前创建的插件实例,并使用来自 php-http/client-common 的 PluginClient 装饰器。

use Facile\OAuth2\HttpClient\OAuth2Plugin;
use Psr\Http\Client\ClientInterface;
use Http\Client\Common\PluginClient;

// create the plugin instance like the previous example
/** @var OAuth2Plugin $oauth2Plugin */
// use your PSR-18 HTTP client
/** @var ClientInterface $psrHttpClient */

// use the PluginClient class from php-http/client-common to decorate your client and use the plugin
$httpClient = new PluginClient($psrHttpClient, [$oauth2Plugin]);

生产环境的高级使用方法

我们可以进行一些改进,以自定义授权行为并提高生产环境中的性能。

自定义授权参数

您可以配置插件以使用默认参数来在 OAuth2 令牌请求中使用

use Facile\OpenIDClient\Service\AuthorizationService;
use Facile\OpenIDClient\Client\ClientInterface;
use Facile\OAuth2\HttpClient\OAuth2Plugin;

// create an OIDC/OAuth2 client and the AuthorizationService from facile-it/php-openid-client
/** @var AuthorizationService $authorizationService */
/** @var ClientInterface $client */

$oauth2Plugin = new OAuth2Plugin(
    $authorizationService,
    $client,
    null,
    [
        // custom default grant parameters
        'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange',
    ]
);

可选地,您可以创建一个自定义的 OAuth2Request(它是一个 PSR-7 请求装饰器)以使用单个请求的授权参数。
请求授权参数将与插件中注入的默认授权参数合并。

use Psr\Http\Client\ClientInterface as HttpClient;
use Psr\Http\Message\RequestInterface;
use Facile\OAuth2\HttpClient\Request\OAuth2Request;

// use your PSR-18 HTTP client configured with our plugin
/** @var HttpClient $psrHttpClient */
// your PSR-7 HTTP request
/** @var RequestInterface $request */

$oauth2Request = (new OAuth2Request($request))
    ->withGrantParams([
        // request grant parameters
        'my-custom-param' => 'my-value',
    ]);
$response = $psrHttpClient->sendRequest($oauth2Request);

令牌交换

具有为每个请求使用自定义授权参数的能力,因此简单地交换令牌(请参阅 Token-Exchange (RFC8693))。

想象一下您的 API 资源(服务 A)受保护,用户应该有自己的个人访问令牌(主题令牌,可能是一个包含用户信息的 JWT)。然后,服务 A 需要向另一个受保护的资源服务器(服务 B)发出请求。您不能使用用户提供的同一访问令牌,因为 JWT 的受众仅为服务 A,因此您需要用具有服务 B 受众的另一个令牌进行令牌交换。

use Psr\Http\Client\ClientInterface as HttpClient;
use Psr\Http\Message\RequestInterface;
use Facile\OpenIDClient\Service\AuthorizationService;
use Facile\OpenIDClient\Client\ClientInterface;
use Facile\OAuth2\HttpClient\OAuth2Plugin;
use Facile\OAuth2\HttpClient\Request\OAuth2Request;

// create an OIDC/OAuth2 client and the AuthorizationService from facile-it/php-openid-client
/** @var AuthorizationService $authorizationService */
/** @var ClientInterface $client */

$plugin = new OAuth2Plugin(
    $authorizationService,
    $client,
    null,
    [
         // inject default parameters:
        'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange',
        'subject_token_type' => 'urn:ietf:params:oauth:token-type:access_token',
        'audience' => 'my-resource-server',
    ]
);

// use your PSR-18 HTTP client configured with our plugin
/** @var HttpClient $apiClient */
// your HTTP request
/** @var RequestInterface $request */

// the subject token can be the access token provided by the user requesting your APIs
$subjectToken = '';

// then you need to call another service (my-resource-server), but you need another access token with the right audience
$apiRequest = (new OAuth2Request($request))
    ->withGrantParams([
        'subject_token' => $subjectToken, // the subject token
    ]);
$response = $apiClient->sendRequest($apiRequest);

缓存的授权

为了提高性能并避免在不需要时获取令牌,我们可以使用 CachedProvider 缓存令牌。

缓存基于客户端、请求 URI 主机和授权参数。

use Facile\OpenIDClient\Service\AuthorizationService;
use Facile\OpenIDClient\Client\ClientInterface;
use Facile\OAuth2\HttpClient\OAuth2Plugin;
use Facile\OAuth2\HttpClient\Authorization\CachedProvider;
use Psr\SimpleCache\CacheInterface;

// create an OIDC/OAuth2 client and the AuthorizationService from facile-it/php-openid-client
/** @var AuthorizationService $authorizationService */
/** @var ClientInterface $client */
// use your PSR-16 simple-cache implementation
/** @var CacheInterface $cache */

$oauth2Plugin = new OAuth2Plugin(
    $authorizationService,
    $client,
    new CachedProvider($cache /*, default TTL (in seconds) = 1800 */)
);

按请求授权

有时,只有少量资源受保护,因此您不必在每次 HTTP 请求中都进行授权请求。

您可以禁用它,因此只有当资源服务器请求时(使用 401403 响应代码)才会进行授权。

use Facile\OpenIDClient\Service\AuthorizationService;
use Facile\OpenIDClient\Client\ClientInterface;
use Facile\OAuth2\HttpClient\OAuth2Plugin;

// create an OIDC/OAuth2 client and the AuthorizationService from facile-it/php-openid-client
/** @var AuthorizationService $authorizationService */
/** @var ClientInterface $client */

$oauth2Plugin = new OAuth2Plugin(
    $authorizationService,
    $client,
    null,
    [],
    false // disable authorization for each request
);