tracardi-1.0.x-dev/src/Services/Middleware/EnsureAccessTokenExistsMiddleware.php

src/Services/Middleware/EnsureAccessTokenExistsMiddleware.php
<?php

namespace Drupal\tracardi\Services\Middleware;

use Drupal\tracardi\Services\AccessToken\Context\AccessTokenContextInterface;
use Drupal\tracardi\Services\AccessToken\Storage\AccessTokenStorageInterface;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\Response;
use League\OAuth2\Client\Token\AccessToken;
use Psr\Http\Message\RequestInterface;

final class EnsureAccessTokenExistsMiddleware {
  private AccessTokenStorageInterface $accessTokenStorage;

  private AccessTokenContextInterface $accessTokenContext;

  public function __construct(
    AccessTokenStorageInterface $accessTokenStorage,
    AccessTokenContextInterface $accessTokenContext
  ) {
    $this->accessTokenStorage = $accessTokenStorage;
    $this->accessTokenContext = $accessTokenContext;
  }

  public function __invoke(callable $handler): callable {
    return function (RequestInterface $request, array $options) use ($handler) {
      if ($request->hasHeader('Authorization')) {
        return $handler($request, $options);
      }

      $token = $this->accessTokenContext->getAccessToken();
      $request = $this->authenticateRequest($request, $token);

      /** @var \GuzzleHttp\Promise\PromiseInterface $promise */
      $promise = $handler($request, $options);
      if (!$this->isUnauthorized($promise)) {
        return $promise;
      }

      // In principle the Tracardi OAuth token has no expiry. Should we still
      // get a 401, we'll fetch a new token and try again.
      $accessToken = $this->fetchNewToken();
      $request = $this->authenticateRequest($request, $accessToken);

      return $handler($request, $options);
    };
  }

  private function authenticateRequest(RequestInterface $request, AccessToken $accessToken): RequestInterface {
    return $request->withHeader('Authorization', 'Bearer ' . $accessToken->getToken());
  }

  private function isUnauthorized(PromiseInterface $promise): bool {
    /** @var Response $response */
    $response = $promise->wait();

    return $response->getStatusCode() === 401;
  }

  private function fetchNewToken(): AccessToken {
    $this->accessTokenStorage->clear();

    return $this->accessTokenContext->getAccessToken();
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc