How to resolve error in Google Storage Client in Symfony? - php

I am developing a project in Symforny 5 and I want to use Google Cloud Storage, install thephpleague / flysystem-bundle with superbalist / flysystem-google-storage support, as indicated in the documentation, generate the credentials.json in Google Console and the bucket, but I get the following error:
{
"error": {
"code": 401,
"message": "Invalid Credentials",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"locationType": "header",
"location": "Authorization"
}
]
}
}
\vendor\google\cloud-core\src\RequestWrapper.php (line 362)
Configurations:
flysystem:
storages:
default.storage:
adapter: 'local'
options:
directory: '%kernel.project_dir%/var/storage/default'
gcs.storage:
adapter: 'gcloud'
options:
client: 'gcloud_client_service' # The service ID of the Google\Cloud\Storage\StorageClient instance
bucket: 'test-storage'
#prefix: 'optional/path/prefix'
api_url: 'https://storage.googleapis.com'
In service.yml
gcloud_client_service:
class: Google\Cloud\Storage\StorageClient
arguments:
- projectId: 'storage-project'
- keyFilePath: '../credentials.json'

The error you are getting because the credentials are not set correctly. If you want to use the JSON file, a way to solve this issue is setup the credentials inside your code using something like this:
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');
On the other hand, At this this other documentation you can find another way on how to set the configuration of the connection to GCS. Also remember to add the Service Account that you ant to use, going to IAM and adding the "Storage Bucket Admin" role to that SA.
Both of these options should work for you.

A bit late, but maybe it helps someone else. Today I had the same issue on Symfony 5.1, solved it by setting services.yaml this way:
services:
gcloud_client_service:
class: Google\Cloud\Storage\StorageClient
arguments:
$config:
keyFilePath: '%kernel.project_dir%/config/my_testing_config.json'
projectId: 'my-testing-project'

Related

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!
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!
This issue is being generated due to the way you are creating the StorageClient object and specifying the the private key file parameter.
You can find the following example to Pass the path to the service account key in code on Google Cloud Platform site that is a very useful reference for your issue:
namespace Google\Cloud\Samples\Auth;
// Imports the Google Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;
function auth_cloud_explicit($projectId, $serviceAccountPath)
{
# Explicitly use service account credentials by specifying the private key
# file.
$config = [
'keyFilePath' => $serviceAccountPath,
'projectId' => $projectId,
];
$storage = new StorageClient($config);
# Make an authenticated API request (listing storage buckets)
foreach ($storage->buckets() as $bucket) {
printf('Bucket: %s' . PHP_EOL, $bucket->name());
}
}

Laravel Passport authentication issue on AWS server

I'm using Laravel 5.5 with passports for API services. Its working fine after adding the "client credentials" route middleware in local.
'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class
**Local Setup: **
URL: http://localhost/server/public/index.php/api/v1/user/1
I got response as,
{
"status": 200,
"response_time": 0.050323009490967,
"body": {
"user": "admin",
"email": "admin#domain.com"
},
"message": "User found"
}
**AWS Setup: **
But, when I move to AWS server it won't authenticate.
URI: http://api_server.com/server/public/index.php/api/v1/user/1
I got error as,
{
"message": "Unauthenticated."
}
Both installations are same, and I can get access-token and reset-token by its endpoints.
But POST/GET/PUT/DELETE API calls are now allowed on AWS server.
Why it's not supporting on AWS?
Any other ways to solve this?
[Note: "web" group's "POST/GET/PUT/DELETE" routes are working fine.]
you can check for security groups .. where many traffic groups ports are by default blocked.

Error in create object permission to Google Storage Bucket programmatically.

I have created a Bucket using UI of google console. I want to upload some object in the Bucket programmatically. I've checked the documentation from Google.
https://cloud.google.com/storage/docs/object-basics#upload
$storage = new StorageClient();
$file = fopen($source, 'r');
$bucket = $storage->bucket($bucketName);
$object = $bucket->upload($file, [
'name' => $objectName
]);
printf('Uploaded %s to gs://%s/%s' . PHP_EOL, basename($source), $bucketName, $objectName);
Problem is, Returning an error regarding to the permission.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "starting-account-f8mo7two5s1#kjs-speech-api-1506584214035.iam.gserviceaccount.com does not have storage.objects.create access to object kjs-lms/0.mp3."
}
],
"code": 403,
"message": "starting-account-f8mo7two5s1#kjs-speech-api-1506584214035.iam.gserviceaccount.com does not have storage.objects.create access to object kjs-lms/0.mp3."
}
}
I tried to grant the permission in IAM Roles but still same error.
The account that you're using to run your PHP program doesn't have write access to the bucket. Are you running it in app engine or another Google Cloud environment like GCE? In that case, your program is likely running with Application Default Credentials, which are not the same thing as running as yourself. Grant the account mentioned in the error message ownership of the bucket in question, and the issue should be resolved.

Using Google OAuth 2.0 for Server to Server Applications PHP

I've been following this guide perfectly https://developers.google.com/api-client-library/php/auth/service-accounts in an attempt to get any little bit of information back from google, yet I keep getting a 403 Insufficient Permission.
I have created a service account, and it has given me a little json file with a private key, project ID, a client email and client ID, and lots of other nifty stuff that I cannot share here on stack overflow.
I then delegated domain wide authority to the service account to speciifc API scopes. https://www.googleapis.com/auth/analytics.readonly I did this through Google Apps domain's admin console.
I then prepared to make an authorized api call with this little bit of php.
<?php
require_once __DIR__ . '/vendor/autoload.php';
date_default_timezone_set('America/Los_Angeles');
$user_to_impersonate = 'my_real_email#companyname.com';
putenv('GOOGLE_APPLICATION_CREDENTIALS=/Users/alexfallenstedt/Desktop/Code/sticky-dash/service-account.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$client->setSubject($user_to_impersonate);
$sqladmin = new Google_Service_SQLAdmin($client);
$response = $sqladmin->instances->listInstances('examinable-example-123')->getItems();
echo json_encode($response) . '\n';
?>
I run this php file in console, and I keep getting this error.
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
I am lost. My whole team is lost. We've gone through this multiple times. How can we set up server to server communication to fetch our google analytics reporting api data?
I ended up forgetting the beta version, and instead referred to v3 of two-legged OAuth. https://developers.google.com/analytics/devguides/reporting/core/v3/quickstart/service-php

PHP Google API service accounts

I am currently struggling to get access to the google api when impersonating a user.
I can connect as that user however I am getting an error where I am presented with an error:
"error": {
"errors": [
{
"domain": "global",
"reason": "appNotAuthorizedToFile",
"message": "The user has not granted the app <app id> write access to the file <file id>",
"locationType": "header",
"location": "Authorization"
}
],
}
The recommended resolution is to use google Picker and get the user to allow my app to access this file. However as I am using a service account with domain wide delegation and g-suite enabled I thought this wasn't necessary.
my current php code is:
$client = new Google_Client();
$client->setApplicationName($appName);
$client->setAuthConfig($credentials);
$client->addScope($scopes);
$client->setClientId($key);
$client->useApplicationDefaultCredentials();
$client->setSubject($userTobe);
$client->setAccessType('offline');
I am using putenv to push my service_account.json into my file. I followed the quick start as it suggested. I have enabled all the required scopes in the security console. If I specify getRefreshTokenwithAssertion() i can get an access_token starting with ya29. however this still presents the error above.
I am currently at a loss on where to go from here. Any help would be greatly appreciated.
Which scopes are you using? Please ensure you are setting the drive auth scope in your application: https://www.googleapis.com/auth/drive (Google_service_Drive::DRIVE)
Has the client and scopes been authorized in the admin console?
admin console => security => Advanced settings => manage API client access

Categories