Google Analytics Reporting API using OAuth 2 with ColdFusion

Google Analytics provides a Core Reporting API (Version 3) that allows for the extraction of data into custom dashboards and interfaces. The API uses OAuth 2 for authentication with refresh tokens for offline access. There is also OAuth 1 with an API key access available for certain situations (not covered in this post):

If your application has certain unusual authorization requirements, such as logging in at the same time as requesting data access (hybrid) or domain-wide delegation of authority (2LO), then you cannot currently use OAuth 2.0 tokens. In such cases, you must instead use OAuth 1.0 tokens and an API key. You can find your application’s API key in the Google APIs Console, in the Simple API Access section of the API Access pane.

For everything else, here are the first steps, a demo, and a link to the full code on github.

Steps

  1. Register the app with Google
  2. Create login URL and retrieve “code”
  3. Exchange “code” for access token
  4. Send access token with API requests (details in this post)

Google details the instructions in Using OAuth 2.0 to Access Google APIs.

Steps for registering your app can be found in APIs Client Library for PHP.

Google scope values for its API’s can be found in the OAuth 2.0 Playground.

Create Login URL and Retrieve “Code”

Parameters for Login URL

Client id and client secret are set by Google when the app is registered for api access in the Google APIs Console.

The redirect uri is a location on the server that the user is sent to after authenticating. This uri is registered in the Google APIs Console during app registration.

These values can be included in the application.cfc:

<cfset request.oauthSettings = {scope = "https://www.googleapis.com/auth/analytics.readonly",
      client_id = "YOUR-CLIENT-ID.apps.googleusercontent.com",
      client_secret = "YOUR-CLIENT-SECRET",
      redirect_uri = "YOUR-REDIRECT-URI",
      state = "optional"} />

User Login URL

The login URL will prompt the user for permission to access their Google content via the app and a “code” request variable will be returned in the URL. See Forming the URL for more detailed information.

<!--- create login url --->
<cfset loginURL = "https://accounts.google.com/o/oauth2/auth?scope=" & request.oauthSettings["scope"]
                   & "&redirect_uri=" & request.oauthSettings["redirect_uri"]
                   & "&response_type=code&client_id=" & request.oauthSettings["client_id"]
                   & "&access_type=online" />

<a href="#loginURL#">Login with Google account that has access to analytics</a>

Exchange “Code” for Access Token

If access type was set to “offline” in the login URL, a refresh token will be sent with the access token so the data can be accessed without prompting the user again. Refesh token storage and use will be covered in another post.

<!--- get access token if code returned and access token not issued --->
<cfif isDefined("URL.code") AND URL.code NEQ "access_denied">
<cfinvoke component="ga" method="googleOauth2Login">
        <cfinvokeargument name="code" value="#URL.code#" />
    </cfinvoke>
</cfif>

----- in component -----

<cffunction name="googleOauth2Login" access="public" hint="GA account authorization">
        <cfargument name="code" type="string" required="yes" default="">
        <cfargument name="gaOauthUrl" type="string" required="no" default="https://accounts.google.com/o/oauth2/token">
        <!---cfscript provides cleaner local var set--->
        <cfscript>
			var jsonResponse = StructNew();
			var accessToken = "";
			var expires_in = "";
		</cfscript>
           
        <cfhttp url="#arguments.gaOauthUrl#" method="post">
       		<cfhttpparam name="code" type="formField" value="#arguments.code#">
       		<cfhttpparam name="client_id" type="formField" value="#request.oauthSettings['client_id']#">
       		<cfhttpparam name="client_secret" type="formField" value="#request.oauthSettings['client_secret']#">
       		<cfhttpparam name="redirect_uri" type="formField" value="#request.oauthSettings['redirect_uri']#">
       		<cfhttpparam name="grant_type" type="formField" value="authorization_code">
		</cfhttp>
    
        <cfset jsonResponse = DeserializeJSON(cfhttp.filecontent) />
        <cfif StructKeyExists(jsonResponse, "access_token")>
	        <cfset accessToken = jsonResponse.access_token />
	        <cfset expires_in = jsonResponse.expires_in />
        <cfelse>
         	<cfset accessToken = "Authorization Failed " & cfhttp.filecontent />
        </cfif>

        <cflock scope="session" type="exclusive" timeout="5">
			<cfset session.ga_accessToken = accessToken />
			<cfset session.ga_accessTokenExpiry = DateAdd("s",expires_in,Now()) />
		</cflock>
		<!---send back to login to show auth error message or profile select options--->
		<!---this also strips code URL param to prevent inadvertent refresh with one-time use code--->
		<cflocation url="login.cfm" addtoken="no"/>
    </cffunction>

You now have an access token to present to the Google Analytics API (or any Google API you specify in the scope) and now you can request the data.

Full demo and code below:

Demo

Download code

Posted in ColdFusion, Google Analytics. Tags: , . Permalink. Both comments and trackbacks are closed.