Search code examples
phpxamppgoogle-cloud-platformgoogle-api-php-clientgoogle-authentication

Google Cloud API PHP Client Authentication using Service Account


I'm working with a project using PHP and need to implement Google Cloud APIs using PHP Client library, but the authentication does not seem to be working for me. I have created a service account and granted the project owner permissions and I don't want to make authentication by using the GOOGLE_DEFAULT_CREDENTIALS environment variable, I want to use service account authentication.

Here's what I have tried:

require 'vendor/autoload.php';
use Google\Cloud\Core\ServiceBuilder;
use Google\Cloud\Storage\StorageClient;

// Authentication with Google Cloud Platform
$client = new ServiceBuilder([
    'keyFilePath' => 'api-project-374381085870-eaf930d9ffd7.json'
]);
$client = new StorageClient();
$bucket = $client->bucket('storage_client');

// Upload a file to the bucket.
$bucket->upload(
    fopen('file.txt', 'r')
);

But it returns an error as:

Warning: file_get_contents(/Users/abdul/.config/gcloud/application_default_credentials.json): failed to open stream: Permission denied in /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/auth/src/CredentialsLoader.php on line 102

Warning: file_get_contents(/Users/abdul/.config/gcloud/application_default_credentials.json): failed to open stream: Permission denied in /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/auth/src/CredentialsLoader.php on line 102

Fatal error: Uncaught exception 'Google\Cloud\Core\Exception\ServiceException' with message '{ "error": { "errors": [ { "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } } ' in /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/cloud-core/src/RequestWrapper.php:263 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/cloud-core/src/RequestWrapper.php(168): Google\Cloud\Core\RequestWrapper->convertToGoogleException(Object(GuzzleHttp\Exception\ClientException))

1 /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/cloud-core/src/Upload/MultipartUploader.php(65):

Google\Cloud\Core\RequestWrapper->send(Object(GuzzleHttp\Psr7\Request), Array) #2 /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/cloud-storage/src/Bucket.php(283): Google\Cloud\Core\Upload\MultipartUploader->upload() #3 /Applications/XAMPP/xamppf in /Applications/XAMPP/xamppfiles/htdocs/storage/vendor/google/cloud-core/src/RequestWrapper.php on line 263

Help me, please!

Thanks in advance!


Solution

  • The keyfile configuration must be provided to the client which is being called. The ServiceBuilder is often convenient because it allows you to create a single instance with your configuration, and that configuration is passed to each new client.

    In your example, you've created a ServiceBuilder instance with a keyfile, but you're not using that instance to call Storage.

    Two options:

    use Google\Cloud\Core\ServiceBuilder;
    
    $cloud = new ServiceBuilder([
        'keyFilePath' => 'my-keyfile.json'
    ]);
    
    $storage = $cloud->storage();
    

    or

    use Google\Cloud\Storage\StorageClient;
    
    $storage = new StorageClient([
        'keyFilePath' => 'my-keyfile.json'
    ]);
    

    In both examples, $storage should be authenticated and ready to use!