facile-it / php-oauth2-http-client
OpenID/OAuth2 授权支持的 HTTPlug 插件
Requires
- php: ^7.2 || ^8.0
- ext-json: *
- facile-it/php-openid-client: ^0.1.2 || ^0.2.0
- php-http/client-common: ^2.3
- psr/simple-cache: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.15
- jangregor/phpstan-prophecy: ^0.6.2
- laminas/laminas-diactoros: ^2.1
- php-http/curl-client: ^2.1
- phpspec/prophecy: ^1.10.3
- phpstan/extension-installer: ^1.0
- phpstan/phpstan: ^0.12.18
- phpstan/phpstan-deprecation-rules: ^0.12.2
- phpstan/phpstan-strict-rules: ^0.12.2
- phpunit/phpunit: ^8.5.8 || ~9.0.2
This package is auto-updated.
Last update: 2024-09-04 22:35:36 UTC
README
OAuth2 授权的 HTTPlug 插件。
此软件包允许您使用兼容的 PSR-18 HTTP 客户端,并在请求外部受保护资源时处理 OAuth2 授权。
此软件包基于 facile-it/php-openid-client 进行身份验证。您需要了解如何使用它,特别是创建客户端。
安装
composer require facile-it/php-oauth2-http-client
HTTPlug 插件
此库提供了一个 HTTPlug 插件来处理授权,因此您需要创建其实例。
客户端将用于身份验证和对令牌端点的请求。
当资源服务器以 401
或 403
状态码响应时,此插件会尝试进行授权请求以获取 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 请求中都进行授权请求。
您可以禁用它,因此只有当资源服务器请求时(使用 401
或 403
响应代码)才会进行授权。
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 );