Files
alfa-bank-sdk/src/Requests/Auth/GetTokenRequest.php
Anatoliy Poloz 2964c391b5 Add H2H authentication service and new example flows
- Implement H2H authentication service for secure client authentication
- Add new examples for authorization code flow and H2H auth service
- Include example for generating client secret
- Update core connector and token request functionality
- Enhance README with new features

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-01-23 20:58:30 +03:00

89 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
/*
// MODULE_CONTRACT: Represents the OAuth 2.0 token acquisition request.
// RESPONSIBILITY: To define the endpoint, method, and body for exchanging an authorization code or client credentials for an access token.
// INPUTS: Client credentials, grant type, and optionally an authorization code and redirect URI.
// OUTPUTS: TokenData (DTO containing the access token, refresh token, and expiry).
// LINKS: AlfaBankConnector.php#authentication_handler
*/
namespace Apoloz\AlfaBank\Requests\Auth;
// <SECTION name="module_imports" intent="Import necessary DTOs and Saloon framework components.">
// <BELIEF_STATE "The request needs the `TokenData` DTO to structure the response, and Saloon's `HasFormBody` trait because the OAuth 2.0 spec requires token requests to be `application/x-www-form-urlencoded`.">
use Apoloz\AlfaBank\Data\Auth\TokenData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasFormBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for the OAuth 2.0 token endpoint request.">
// <BELIEF_STATE "Encapsulating the token request in a dedicated class makes the authentication flow explicit, reusable, and easy to test or modify.">
class GetTokenRequest extends Request implements HasBody
{
// <SECTION name="feature_traits" intent="Enable the form body serialization for this request.">
// <BELIEF_STATE "The OAuth 2.0 specification for token endpoints mandates a `Content-Type` of `application/x-www-form-urlencoded`. The `HasFormBody` trait correctly implements this serialization behavior.">
use HasFormBody;
// </SECTION>
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for the token request.">
// <BELIEF_STATE "As per the OAuth 2.0 standard (RFC 6749), the token endpoint must be accessed via a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject all required parameters for the token request.">
// <BELIEF_STATE "The constructor includes parameters for both Authorization Code and Client Credentials flows. A default `grantType` is provided for the most common flow, but can be overridden, making the request class flexible.">
public function __construct(
protected string $clientId,
protected string $clientSecret,
protected ?string $code = null,
protected ?string $redirectUri = null,
protected ?string $refreshToken = null,
protected string $grantType = 'authorization_code'
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the token endpoint.">
// <BELIEF_STATE "The `/oidc/token` endpoint is the standard path for OpenID Connect token acquisition, which this API adheres to.">
public function resolveEndpoint(): string
{
return '/oidc/token';
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the form-urlencoded body for the token request.">
// <BELIEF_STATE "This method builds the request body array. It correctly maps the class properties to the `snake_case` parameter names expected by the OAuth 2.0 standard.">
protected function defaultBody(): array
{
$body = [
'grant_type' => $this->grantType,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
if ($this->grantType === 'authorization_code') {
$body['code'] = $this->code;
$body['redirect_uri'] = $this->redirectUri;
}
if ($this->grantType === 'refresh_token') {
$body['refresh_token'] = $this->refreshToken;
}
return $body;
}
// </SECTION>
// <SECTION name="response_dto_caster" intent="Transform the raw JSON response into a structured TokenData DTO.">
// <BELIEF_STATE "Automatically casting the JSON token response into a `TokenData` DTO provides type safety and a clean, object-oriented way to access token properties like `access_token` and `expires_in`.">
public function createDtoFromResponse(Response $response): TokenData
{
return TokenData::from($response->json());
}
// </SECTION>
}