path = $path; $this->folderId = $folderId; // Need to remove header/metadata from private key if (\strpos($privateKey, "PLEASE DO NOT REMOVE THIS LINE!") === 0) { $privateKey = \substr($privateKey, \strpos($privateKey, "\n") + 1); } $this->privateKey = $privateKey; $this->keyId = $keyId; $this->serviceAccountId = $serviceAccountId; } public function post(string $path, array $post): array { $token = $this->getToken(); $path = $this->path . $path; $post['folderId'] = $this->folderId; $response = Http::withToken($token) ->timeout(30) ->post($path, $post); $data = $response->json(); if ($data !== null && $response->status() === 200) { return $data; } $message = $data['message'] ?? 'Error in request'; throw new TranslateException($message, $response->status()); } private function getToken(): string { $cacheName = self::class . '_token'; $token = Cache::get($cacheName); if ($token !== null) { return $token; } $token = $this->createNewToken(); Cache::put($cacheName, $token['iamToken'], Carbon::createFromDate($token['expiresAt'])); return $token['iamToken']; } private function getJWTToken(): string { $jwk = JWKFactory::createFromKey( $this->privateKey, null, [ 'alg' => 'PS256', 'use' => 'sig', 'kid' => $this->keyId, ] ); $algorithmManager = new AlgorithmManager([new PS256()]); $jwsBuilder = new JWSBuilder($algorithmManager); $payload = \json_encode([ 'iss' => $this->serviceAccountId, 'aud' => "https://iam.api.cloud.yandex.net/iam/v1/tokens", 'iat' => time(), 'nbf' => time(), 'exp' => time() + 600, ]); $jws = $jwsBuilder ->create() ->withPayload($payload) ->addSignature($jwk, ['alg' => 'PS256', 'typ'=>'JWT', 'kid' => $this->keyId]) ->build(); $serializer = new CompactSerializer(); return $serializer->serialize($jws, 0); } private function createNewToken(): array { $jwtToken = $this->getJWTToken(); $token = Http::timeout(30) ->post('https://iam.api.cloud.yandex.net/iam/v1/tokens', ['jwt' => $jwtToken]); return $token->json(); } }