My Business
5K members online now
5K members online now
For developers who are using the Google My Business API to manage locations
Guide Me
star_border
Reply

Error (401) The request does not have valid authentication credentials

[ Edited ]
Visitor ✭ ✭ ✭
# 1
Visitor ✭ ✭ ✭

Attempting to access GMB account records, but getting the following error:
Error calling GET http://apps.test.kahalamgmt.com/google/mybizapi/test.php: (401) The request does not have valid authentication credentials.

Thank you

PHP 5.3.3
Google API PHP Client 1.1.7
GMB API v3

 

<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors',1);
define('CLIENT_CREDENTIALS', dirname(__DIR__) . '/includes/credentials/client_secret.json');
require(dirname(__DIR__) . '/includes/functions/autoloader.php');
require(dirname(__DIR__) . '/includes/mybusiness/Mybusiness.php');

$client = new Google_Client();
$client->setAuthConfigFile(CLIENT_CREDENTIALS);
$client->setScopes(array('https://www.googleapis.com/auth/plus.business.manage'));
$redirect_uri = 'http://apps.test.kahalamgmt.com/google/mybizapi/test.php';

$mybusinessService = new Google_Service_Mybusiness($client);
$accounts = $mybusinessService->accounts;

try 
{	
	$accountsList = $accounts->listAccounts()->getAccounts();
} 
catch (Exception $e) 
{
	die("Caught exception: " . $e->getMessage() . "\n");
}
1 Expert replyverified_user

Re: Error (401) The request does not have valid authentication credentials

Google Employee
# 2
Google Employee

Hi @Troy C,

 

Judging from the source code you provided, you didn’t request user consent during OAuth 2.0 authorization and you set the wrong value for the $redirect_uri variable. Please choose a correct redirect URI for your installed application and set the redirect URI for your application to work.

 

Since you are building a command-line installed application to integrate the Google My Business API, you should make sure that when you create an OAuth 2.0 client ID through the Google Developers Console, you specify that this is an Installed application, then select "Other" as the application type.

 

Please follow the code snippet below to use the OAuth 2.0 for authentication and authorization and persist the refresh token in your installed application with the Google API Client Library for PHP:

include_once "Mybusiness.php";

 

define('APPLICATION_NAME', 'User Query - Google My Business API');

define('CREDENTIALS_PATH', '/path/to/credentials.json');

define('CLIENT_SECRET_PATH', '/path/to/client_secrets.json');

 

if (php_sapi_name() != 'cli') {

 throw new Exception('This application must be run on the command line.');

}

 

$redirect_uri = 'urn:ietf:wg:oauth:2.0:oob';

 

$client = new Google_Client();

$client->setApplicationName(APPLICATION_NAME);

$client->setAuthConfigFile(CLIENT_SECRET_PATH);

$client->addScope("https://www.googleapis.com/auth/plus.business.manage");

$client->setRedirectUri($redirect_uri);

 

// For retrieving the refresh token

$client->setAccessType("offline");

$client->setApprovalPrompt("force");

 

/************************************************

 We are going to create the Google My Business API

 service, and query it.

************************************************/

$mybusinessService = new Google_Service_Mybusiness($client);

 

// Load previously authorized credentials from a file.

$credentialsPath = CREDENTIALS_PATH;

if (file_exists($credentialsPath)) {

 $accessToken = file_get_contents($credentialsPath);

} else {

 // Request authorization from the user.

 $authUrl = $client->createAuthUrl();

 printf("Open the following link in your browser:\n%s\n", $authUrl);

 print 'Enter verification code: ';

 $authCode = trim(fgets(STDIN));

 

 // Exchange authorization code for an access token.

 $accessToken = $client->authenticate($authCode);

 

 // Store the credentials to disk.

 if (!file_exists(dirname($credentialsPath))) {

   mkdir(dirname($credentialsPath), 0700, true);

 }

 file_put_contents($credentialsPath, $accessToken);

 printf("Credentials saved to %s\n", $credentialsPath);

}

$client->setAccessToken($accessToken);

 

// Refresh the token if it's expired.

if ($client->isAccessTokenExpired()) {

 $client->refreshToken($client->getRefreshToken());

 file_put_contents($credentialsPath, $client->getAccessToken());

}

 

$accounts = $mybusinessService->accounts;

$locations = $mybusinessService->accounts_locations;

 

// Lists all accounts for the authenticated user

$accountsList = $accounts->listAccounts()->getAccounts();

var_dump($accountsList);

 

Thanks,

Terry

Re: Error (401) The request does not have valid authentication credentials

[ Edited ]
Visitor ✭ ✭ ✭
# 3
Visitor ✭ ✭ ✭

Terry,
We already have the OAuth credentials and approval from Google.
We want to run this as a php application that will run on a server and not the command line, to update our account records nightly. Does the code you posted still apply or should I be using something else.

Thanks,
Troy

Re: Error (401) The request does not have valid authentication credentials

Google Employee
# 4
Google Employee

Hi @Troy C,

 

If you are developing a web server application, please follow the code snippet below to use the OAuth 2.0 for authentication and authorization and persist the refresh token with the Google API Client Library for PHP:

include_once "Mybusiness.php";

 

define('APPLICATION_NAME', 'User Query - Google My Business API');

define('CREDENTIALS_PATH', '/path/to/credentials.json');

define('CLIENT_SECRET_PATH', '/path/to/client_secrets.json');

 

$redirect_uri = '<YOUR_REDIRECT_URI>';

 

$client = new Google_Client();

$client->setApplicationName(APPLICATION_NAME);

$client->setAuthConfigFile(CLIENT_SECRET_PATH);

$client->addScope("https://www.googleapis.com/auth/plus.business.manage");

$client->setRedirectUri($redirect_uri);

 

// For retrieving the refresh token

$client->setAccessType("offline");

$client->setApprovalPrompt("force");

 

/************************************************

 We are going to create the Google My Business API

 service, and query it.

************************************************/

$mybusinessService = new Google_Service_Mybusiness($client);

 

$credentialsPath = CREDENTIALS_PATH;

if (isset($_GET['code'])) {

 // Exchange authorization code for an access token.

 $accessToken = $client->authenticate($_GET['code']);

 // Store the credentials to disk.

 if (!file_exists(dirname($credentialsPath))) {

   mkdir(dirname($credentialsPath), 0700, true);

 }

 file_put_contents($credentialsPath, $accessToken);

 $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];

 header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));

}

 

// Load previously authorized credentials from a file.

if (file_exists($credentialsPath)) {

 $accessToken = file_get_contents($credentialsPath);

 $client->setAccessToken($accessToken);

 // Refresh the token if it's expired.

 if ($client->isAccessTokenExpired()) {

   $client->refreshToken($client->getRefreshToken());

   file_put_contents($credentialsPath, $client->getAccessToken());

 }

} else {

 // Request authorization from the user.

 $authUrl = $client->createAuthUrl();

}

 

$accounts = $mybusinessService->accounts;

$locations = $mybusinessService->accounts_locations;

 

// Lists all accounts for the authenticated user

$accountsList = $accounts->listAccounts()->getAccounts();

var_dump($accountsList);

 

Thanks,

Terry

Re: Error (401) The request does not have valid authentication credentials

[ Edited ]
N/A
# 5
N/A

Terry,
We have the auth client id and I downloaded the client_secret.json file and that seems to contain the client id, client secret ect. What is the credentials.json and is this a file I download or create myself?

Thanks,
Troy

Re: Error (401) The request does not have valid authentication credentials

Google Employee
# 6
Google Employee

Hi Troy,

 

The credentials.json file in my code snippet contains an access token and a refresh token you obtain and store on your local disk from the Google Authorization Server during OAuth 2.0 Authorization. An access token has a limited lifetime, therefore your web application should request and store a refresh token for future use. Once the access token expires, the application uses the refresh token to obtain a new one. For details, see Using OAuth 2.0 for Web Server Applications.

 

Thanks,

Terry

Re: Error (401) The request does not have valid authentication credentials

N/A
# 7
N/A
Terry,

The if(isset($_GET['code'])) is never being set. So that is keeping the access token from being set and not being written to the file. Is there a process that I am missing that is keeping these values from being returned?
It was my assumption that authorizing a GMB account via Oauth Playground would authorize the account so that it would be available in the API data return.

Re: Error (401) The request does not have valid authentication credentials

Google Employee
# 8
Google Employee

Hi,

 

The $_GET['code'] variable is a PHP variable in an associative array passed to the current script via the URL parameter in the query string that has the code field for an authorization code that your application can use to obtain an access token. The webpage where the $_GET['code'] variable is returned when Google sends responses to your authentication requests is determined by the redirect URI that you set in the Google Developers Console.

 

For simplicity, I suggest you set the redirect URI to the URL of your current script if you are using my code snippet. If you set your redirect URI to the URL of a separate webpage, you can use the following code to redirect to the current script with the query string containing the returned $_GET['code'] variable for an authorization code:

header('Location: <YOUR_CURRENT_SCRIPT_URL>?' . $_SERVER['QUERY_STRING']);

 

Using the OAuth 2.0 Playground to request user consent during OAuth 2.0 authorization for a particular Google Account is for using a service account, but you are using an OAuth 2.0 client ID for a Web Server Application. Therefore, you need to request user consent for your web app and persist the refresh token at least once. You can read more about it here in this thread.

 

Thanks,

Terry

Re: Error (401) The request does not have valid authentication credentials

Visitor ✭ ✭ ✭
# 9
Visitor ✭ ✭ ✭
Terry,

We are new to this and learning as we go. I am going to intervene here and present you with what we are wanting to do. I am thinking we should be using a service account instead.

We are a franchisor of restaurants and have a data set where the franchisee updates their store information. We are trying auto push those changes to google nightly. This scenario falls under the two-legged OAuth method. Seems like we should be using a service account. Thoughts?

Re: Error (401) The request does not have valid authentication credentials

[ Edited ]
Google Employee
# 10
Google Employee

Hi @bwmyers,

 

A service account is typically for server-to-server interactions when the application uses Google APIs to work with its own data rather than a user's data. "Two-legged OAuth" refers to scenarios in which your application calls Google APIs on behalf of the service account, so users aren't directly involved. "Three-legged OAuth" refers to scenarios in which your application calls Google APIs on behalf of end users, and user consent is sometimes required. Your scenario is more related to the term "Three-legged OAuth".

 

Developers often consider using service accounts because they want programmatic access to the API using OAuth 2.0 Authorization without human interactions.

 

Due to the complexities involved in using service accounts with the Google My Business API, a simpler alternative that achieves the same goal of not requiring human interactions for OAuth 2.0 authorization is using the OAuth 2.0 client ID for an installed app or web app flow and persisting the refresh token. This way, your application will always be able to request a new access token when necessary. This process requires a user to manually authorize the application during the OAuth 2.0 flow only once.

 

If you need specific features of a service account, a one-time user consent is required for accessing the Google My Business data on behalf of a particular end user. Please make sure that you create a service account for a whitelisted project to access the Google My Business API in Google Developers Console. The end users will have to log in with their Google Accounts to manually authorize the application using OAuth 2.0 authorization. They need to perform this process only once during the OAuth 2.0 installed application flow or using OAuth 2.0 Playground. When you prepare to make authorized API calls using the service account, you specify the user to impersonate by specifying the email address of the user account. You should be able to access the Google My Business data of the user account that you have previously given user consent for during the OAuth 2.0 installed application flow. If the end users later want to revoke the application’s access to their Google My Business data, they can remove the authorized app from the Apps connected to your account page of their accounts.

 

I suggest you search on this forum for the code snippets to learn how to use the specific client libraries we offer on our Google Developers site.

 

Thanks,

Terry