$jsonKey JSON credential file path or JSON credentials * as an associative array * @param string|null $targetAudience The audience for the ID token. */ public function __construct( $scope, $jsonKey, string $targetAudience = null ) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { throw new InvalidArgumentException('file does not exist or is unreadable'); } $json = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $json, true)) { throw new LogicException('invalid json for auth config'); } } if (!array_key_exists('client_id', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the client_id field' ); } if (!array_key_exists('client_secret', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the client_secret field' ); } if (!array_key_exists('refresh_token', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the refresh_token field' ); } if ($scope && $targetAudience) { throw new InvalidArgumentException( 'Scope and targetAudience cannot both be supplied' ); } $additionalClaims = []; if ($targetAudience) { $additionalClaims = ['target_audience' => $targetAudience]; $this->isIdTokenRequest = true; } $this->auth = new OAuth2([ 'clientId' => $jsonKey['client_id'], 'clientSecret' => $jsonKey['client_secret'], 'refresh_token' => $jsonKey['refresh_token'], 'scope' => $scope, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'additionalClaims' => $additionalClaims, ]); if (array_key_exists('quota_project_id', $jsonKey)) { $this->quotaProject = (string) $jsonKey['quota_project_id']; } } /** * @param callable|null $httpHandler * @param array $metricsHeader [optional] Metrics headers to be inserted * into the token endpoint request present. * This could be passed from ImersonatedServiceAccountCredentials as it uses * UserRefreshCredentials as source credentials. * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_in * @type string $scope * @type string $token_type * @type string $id_token * } */ public function fetchAuthToken(?callable $httpHandler = null, array $metricsHeader = []) { return $this->auth->fetchAuthToken( $httpHandler, $this->applyTokenEndpointMetrics($metricsHeader, $this->isIdTokenRequest ? 'it' : 'at') ); } /** * Return the Cache Key for the credentials. * The format for the Cache key is one of the following: * ClientId.Scope * ClientId.Audience * * @return string */ public function getCacheKey() { $scopeOrAudience = $this->auth->getScope(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getAudience(); } return $this->auth->getClientId() . '.' . $scopeOrAudience; } /** * @return array */ public function getLastReceivedToken() { return $this->auth->getLastReceivedToken(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } /** * Get the granted scopes (if they exist) for the last fetched token. * * @return string|null */ public function getGrantedScope() { return $this->auth->getGrantedScope(); } protected function getCredType(): string { return self::CRED_TYPE; } }