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());
}
}
Related
I want to use Google Cloud Vision API for image recognition, Everything installed fine in my yii2 framework.
I'm getting authentication error like :
> Google\Cloud\Core\Exception\ServiceException
> {
> "error": {
> "code": 403,
> "message": "The request is missing a valid API key.",
> "status": "PERMISSION_DENIED"
> }
> }
> 1. in C:\xampp\htdocs\vofms\vendor\google\cloud-core\src\RequestWrapper.php
> at line 336
> 32732832933033133233333433533633733
How to point my key.json file to GOOGLE_APPLICATION_CREDENTIALS environment variable In yii2 framework.
Thanks
The point you are failing is the Authentication as you are looking at the Cloud Vision library whereas the Cloud Vision is a part of the Google Cloud PHP in which you have the Authentication Guide given which recommends the following.
Once you've obtained your credentials file, it may be used to create an authenticated client.
use Google\Cloud\Core\ServiceBuilder;
// Authenticate using a keyfile path
$cloud = new ServiceBuilder([
'keyFilePath' => 'path/to/keyfile.json'
]);
// Authenticate using keyfile data
$cloud = new ServiceBuilder([
'keyFile' => json_decode(file_get_contents('/path/to/keyfile.json'), true)
]);
If you do not wish to embed your authentication information in your application code, you may also make use of Application Default Credentials.
use Google\Cloud\Core\ServiceBuilder;
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/keyfile.json');
$cloud = new ServiceBuilder();
The GOOGLE_APPLICATION_CREDENTIALS environment variable may be set in your server configuration.
LINUX OR MACOS
export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
For example:
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json"
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.
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.
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.
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