I'm trying to make a server application to routinely pull Google Analytics data from my own GA account. Note, it is a personal, server-side application accessing my own data, i.e. there is no end-user accessing this application.
As such, I registered my application in the Google API Console as a Service Application, which gave me a Client ID and a Private Key. It is my understanding that Service Applications do NOT use Application Secret and Redirect URL as there is no end-user in this server-to-server authentication flow. Indeed, the Google API Console gave me no Secret and did not prompt me for a Redirect URL.
Unfortunately, I can not figure out how to authenticate my Service Application within Google's PHP Client API. There is extensive documentation on authenticating web applications with an end-user.
Google's documentation suggests it is possible to authenticate server-to-server by signing a JWT request with the private key. I just can't figure out how to do within the PHP client API (although I've browsed the source and there's definitely a script that signs a request with the private key.)
Am I missing something here? How can I perform authentication for a Service Application with my private key and the Google PHP client API?
Edited for clarity
Google Analytics API V3 now supports OAuth2 tokens returned by a .p12-signed JWT request. That is, we can now use the Analytics API w/ service accounts.
Currently pulling 4 years of day-by-day metrics, just for the hell of it.
Here's a quick 'n' dirty step-by-step:
Go to the Google API Console and create a new app
In the Services tab, flip the Google Analytics switch
In the API Access tab, click Create an OAuth2.0 Client ID
enter your name, upload a logo, and click Next
select the Service account option and press Create client ID
download your private key
Now you're back on the API Access page. You'll see a section called Service account with a Client ID and Email address
Copy the email address (something like ####@developer.gserviceaccount.com)
Visit your GA Admin and add this email as a user to your properties
This is a must; you'll get cryptic errors otherwise.
Get the latest Google PHP Client API via Github
git submodule add https://github.com/google/google-api-php-client.git google-api-php-client-read-only
Rock 'n' roll (thanks all for tips on updated class names):
// api dependencies
require_once(PATH_TO_API . 'Google/Client.php');
require_once(PATH_TO_API . 'Google/Service/Analytics.php');
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName(APP_NAME); // name of your app
// set assertion credentials
$client->setAssertionCredentials(
new Google_Auth_AssertionCredentials(
APP_EMAIL, // email you added to GA
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents(PATH_TO_PRIVATE_KEY_FILE) // keyfile you downloaded
));
// other settings
$client->setClientId(CLIENT_ID); // from API console
$client->setAccessType('offline_access'); // this may be unnecessary?
// create service and get data
$service = new Google_Service_Analytics($client);
$service->data_ga->get($ids, $startDate, $endDate, $metrics, $optParams);
original workaround below
It seems that, despite ambiguous documentation, most Google APIs do not support service accounts yet, including Google Analytics. They cannot digest OAuth2 tokens returned by a .p12 signed JWT request. So, as of right now, you cannot use Google Analytics API V3 with a service account.
Workaround:
In the Google API console, create a client application.
Follow the steps in the Google PHP Client API examples to generate a
client_auth_url
using yourclient_id
,client_secret
, andredirect_uri
Login to Google using cURL. (Be sure to use a cookie file!)
Open the
client_auth_url
in cURL and complete the form. Make sure you setcurl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
andcurl_setopt($ch, CURLOPT_HEADER, 1);
as theauthorization_code
will be in theLocation:
header of the response.Using your
client_id
,client_secret
,redirect_uri
, and the activation code from Step 4, post a request to the Google's OAuth2 Token machine. Make sure you includegrant_type = "authorization_code"
in your post fields.Hurray, you now have a
refresh_token
that never expires, and a workingaccess_token
! Post a request to the Google's OAuth2 Token machine with yourclient_id
,client_secret
,redirect_uri
, andrefresh_token
when youraccess_token
expires and you'll get a new one.