Google Cloud Vision - PHP - "Request had insufficient authentication scopes" - php

Trying to use Google Cloud vision to analyze files already stored in Google Cloud Storage. My code:
$vision = new VisionClient([
'projectId' => $projectId,
'keyFilePath' => <json key file>,
'scopes' => 'https://www.googleapis.com/auth/cloud-platform'
]);
I grab a full http path to my file, which is valid, but when I:
$image = $vision->image( fopen(<file>, 'r'), [ 'LABEL_DETECTION' ]);
I get the error:
Fatal error: Uncaught exception
'Google\Cloud\Core\Exception\ServiceException' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
}'
I can open the file fine ($x = fopen(filename) works), so I'm not sure what's happening here. Is there a way I can check what my service client has in the way of permissions?

I found the problem - I hadn't properly gone through all authorization steps.

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());
}
}

Google API PHP error 500

I'm using google vision API in one of my PHP script.
Script works well when I'm executing it through the terminal:
php /var/www/html/my_script.php
But when I want to execute it from my browser I'm getting an error 500:
PHP Fatal error: Uncaught
Google\Cloud\Core\Exception\ServiceException: {\n "error": {\n
"code": 401,\n "message": "Request had invalid authentication
credentials. Expected OAuth 2 access token, login cookie or other
valid authentication credential. See
https://developers.google.com/identity/sign-in/web/devconsole-project.",\n
"status": "UNAUTHENTICATED"\n }\n}\n
I don't get why the error message suggests me to use OAuth 2, I don't need my user to log to his google account.
My code is the following:
namespace Google\Cloud\Vision\VisionClient;
require('vendor/autoload.php');
use Google\Cloud\Vision\VisionClient;
$projectId = 'my_project_id';
$path = 'https://tedconfblog.files.wordpress.com/2012/08/back-to-school.jpg';
$vision = new VisionClient([
'projectId' => $projectId,
]);
$image = $vision->image(file_get_contents($path), ['WEB_DETECTION']);
$annotation = $vision->annotate($image);
$web = $annotation->web();
Generally speaking, you will need to provide a service account keyfile when constructing a Google Cloud client. The exception to this is if you're running on Compute Engine, or if you have Application Default Credentials setup. Since you're seeing authentication errors, neither of those appear to be the case.
To obtain a service account and keyfile, check out the documentation.
Once you have created a service account and downloaded the json keyfile, you can provide it to the client library constructor:
<?php
use Google\Cloud\Vision\VisionClient;
$vision = new VisionClient([
'projectId' => $projectId,
'keyFilePath' => '/path/to/keyfile.json'
]);
Once you provide a valid keyfile, you should be able to make authenticated requests to the Vision API.
To avoid this step, you can setup Application Default Credentials on your server or computer.

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