Search code examples
phpgoogle-apioauth-2.0google-analytics-apijwt

Service Applications and Google Analytics API V3: Server-to-server OAuth2 authentication?


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


Solution

  • UPDATE July 21st, 2012

    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:

    1. Go to the Google API Console and create a new app

    2. In the Services tab, flip the Google Analytics switch

    3. 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

    4. 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.

    5. 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
      
    6. 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:

    1. In the Google API console, create a client application.

    2. Follow the steps in the Google PHP Client API examples to generate a client_auth_url using your client_id, client_secret, and redirect_uri

    3. Login to Google using cURL. (Be sure to use a cookie file!)

    4. Open the client_auth_url in cURL and complete the form. Make sure you set curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); and curl_setopt($ch, CURLOPT_HEADER, 1); as the authorization_code will be in the Location: header of the response.

    5. 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 include grant_type = "authorization_code" in your post fields.

    6. Hurray, you now have a refresh_token that never expires, and a working access_token! Post a request to the Google's OAuth2 Token machine with your client_id, client_secret, redirect_uri, and refresh_token when your access_token expires and you'll get a new one.