401 Unauthorized When trying to call a google cloud functions

Solution for 401 Unauthorized When trying to call a google cloud functions
is Given Below:

I have a simple node.js function inside Google Cloud Function (that is called from inside my website’s code) and I used previously the id_token that I got when I’m connected inside Google Cloud SDK and use this: gcloud auth print-identity-token, but it only last 60 minutes, so after that my application can’t use anymore the google cloud function.

So I tried to generate my own token with the help of the service account key: https://cloud.google.com/docs/authentication/production#create_service_account

But I always got a “401 Unauthorized” when I call my link with the “Authorization: Bearer token” header

Maybe it’s because I don’t know what to put inside the “aud” value (inside the payload array)

<?php

namespace MyProjectParser;

use FirebaseJWTJWT;
use GuzzleHttpClient;

abstract class GoogleCloudParser extends AbstractParser
{
    /**
     * Returns the HTML for the given URL
     * @param string $url
     * @return string
     * @throws GuzzleHttpExceptionGuzzleException
     */
    protected function getHTML(string $url): string
    {
        $cloudFunctionURL = "https://region-project-name.cloudfunctions.net/function-name";
        $token = $this->getToken();


        $guzzle = new Client();
        $response = $guzzle->get($cloudFunctionURL, [
            'query' => ['url' => $url],
            'headers' => [
                'Authorization' => "Bearer " . $token
            ]
        ]);

        return $response->getBody()->getContents();
    }

    /**
     * Returns the authentification token for google cloud
     * @return string
     */
    protected function getToken()
    {
        $privateKey = "-----BEGIN PRIVATE KEY-----n...n-----END PRIVATE KEY-----n";
        $publicKey = "-----BEGIN CERTIFICATE-----n...n-----END CERTIFICATE-----n";    

        $payload = [
            'iss' => '[email protected]',
            'sub' => '[email protected]',
            'aud' => 'bucket-name',
            'iat' => time(),
            'exp' => (time() + 3600)
        ];

        $header = [
            "alg" => "RS256",
            "typ" => "JWT",
            "kid" => "private_key_id_of_app_engine_default_service-account"
        ];


        $token = JWT::encode($payload, $privateKey, $header["alg"], $header["kid"]);

        return $token;
    }
}

I tried multiple thing to put on the “aud” but I don’t know what to use… I tried to use the bucket name that I got with this: https://github.com/GoogleCloudPlatform/php-docs-samples/blob/78356e87cc54c1d46df52c0d2f47320329957ce5/auth/src/auth_api_explicit.php

With the cmd line: php src/auth_api_explicit.php myGoogleProjectID gcloud-service-account-file.json

I tried to use “https://cloudfunctions.googleapis.com/”…

I tried to put the full link of my function name inside the google cloud functions.

And I think I have set up everything inside the IAM & Google Cloud platform for my service account.

Any help on this please?

I kinda confused looking at your code because the use says FirebaseJWTJWT; but the service account that you are using for the custom token says App-Engine-default-service-account and in the aud you have a bucket name. After looking for a while I found out that to avoid the 401 error you need to ensure that the service account is authorized in the Domain-wide delegation page of the Admin console for the user in the sub claim (field).

Regarding what you could put in the aud you can try to put https://firebase.googleapis.com/ but again I am not totally sure of this because I am a little confuse with your code.

Best regards.