Retrieving Google+ profile data client side with the sign-in button

Overview profile data retrieval

As you might have noticed, the sign-in button, used in the Client Side Flow Example for Google+ history and the Server Side Flow Example, is a very easy and lightweight way to integrate Google+ communication into your web site. As an experiment (warning: this is not a best practice – most notably, the auth token will expire in an hour) I have played around with the client side flow to show how you can retrieve profile information for a user by authenticating the user and then retrieve their profile.

When you’re done, you can render the profile information and profile photo as the following image shows:

The following steps summarize how you can do this:

  • Render the sign-in button
  • Store the auth-token from the callback
  • Use the credentials to retrieve the profile
  • Render or store the profile data
As you’ll see in the article, this is surprisingly easy and could be useful for quickly pulling user’s information from Google+. To see a live version of the code demonstrated here, login to Google+ and then browse to the Google+ profile retrieval demo page.

Render the sign-in button

The first step in this procedure is to render the sign-in button.  You must first include the plusone.js library from Google:

<!-- Required to render the Google+ sign-in button -->
<script src="https://apis.google.com/js/plusone.js"></script>

Next, you render the sign-in button requesting access to the plus.me scope:

  <div id="signin">
  <g:plus action="connect"
    clientid="[your client id]"
  scope="https://www.googleapis.com/auth/plus.me"
      callback="onSignInCallback"></g:plus>
  </div>

The button renders as follows:

After you have rendered the button and the user authenticates, the callback function, onSignInCallback will be called. This is where you will perform the post-authorization steps.

Of note is that I have created some basic HTML content that will show/hide based on the state and that will be used to render the user data.  The following HTML summarizes the elements I use:

  <div id="signin">
  <g:plus action="connect"
    clientid="[your client id]"
  scope="https://www.googleapis.com/auth/plus.me"
      callback="onSignInCallback"></g:plus>
  </div>
  <div id="showClientData" style="display:none">
    <button onClick="getClientData();">Get Client Data</button>
  </div>
  <div id="clientData">
  </div>

Later on, these elements will be accessed using the getElementById method.

Store the authentication token

The first step to be performed after the user clicks the sign-in button is storing the access token after the user has logged in.  To do this, you should put some JavaScript into your page for storing the authentication credentials and the callback triggered after sign-in.  The following code shows the variables I’m using and how I toggle another button that will trigger profile retrieval.

      var accessToken = null;
      var myProfile = null;
      function onSignInCallback(e){
        accessToken = e.access_token;
        document.getElementById("signin").style.display='none';
        document.getElementById("showClientData").style.display='block';
      }

All this code does is store the access token and displays the button for showing the client data.

The div containing the “Get Client Data” button will now render to give you something like this:

At this point, you’re ready to retrieve the profile information.

Use the credentials to retrieve profile information

Now that you have the access token, you can pass it to the API along with your API key to retrieve the profile data. You will first setup the Google API for the RESTful GET and will use an XML HTTP request (XHR) to query the data.  The following code summarizes how I’m doing this:

      function getClientData(){
        console.log("Getting client data");       

        var xhr = new XMLHttpRequest();
        xhr.open('GET',
          'https://www.googleapis.com/plus/v1/people/me/');
        xhr.setRequestHeader('Authorization',
          'Bearer ' + accessToken);
        xhr.send();

        xhr.onreadystatechange = function() {
          if(this.readyState == 4) {
            myProfile = JSON.parse(xhr.responseText);
            console.log(myProfile);
            drawDataToDiv();
          }
        }
      }

The onreadystatechange function will listen for when the state reaches the value, complete, indicating the response has returned. Note that the responseText from the XHR will need to be parsed to create a JavaScript object. At this point you have the profile as a nifty object that you can access like any other object in JavaScript.

Render or store the profile data

Now that you have the profile as an object, you can access the members representing the profile.  In my the following code I access the object members to populate the inner HTML for the div that I use for demonstrative purposes. The following code shows how I retrieve member data and set the innerHTML of my target div to their content.

      function drawDataToDiv(){
        var divMarkup = "<img src='" + myProfile["image"].url + "&sz=200' /><hr>";
        divMarkup    += "<ul>";
        divMarkup    += "  <li>" + myProfile["displayName"] + "</li>";
        divMarkup    += "  <li>" + myProfile["tagline"] + "</li>";
        divMarkup    += "  <li><a href='" + myProfile["url"] + "'>Profile Link</a></li>";
        divMarkup    += "</ul>";
        document.getElementById("clientData").innerHTML = divMarkup;
      }

At this point, you will see the user’s profile data rendered in a format similar to the following:


Notes and conclusions

I’ll start by saying that this example better serves as a proof of concept and isn’t the preferred way to retrieve profile information. Ideally, you will want to use the server-side flow so that you can refresh the access token – functionality that is deliberately prevented because storing the credentials client-side is less secure. If you are only interested in authentication, you can use Federated login with OpenID for Google Account Users or OAuth 2.0 for login.

Next, it’s worth noting that this still could be useful in getting information from a user’s profile as opposed to making them set all the data themselves on your service.  For example, if you have a forum and want to let the user pull their profile image into their avatar, you could use the client side flow to get an image URL that you would then retrieve server side and store.

Furthermore, what’s cool from this flow is that it demonstrates how you can get client side access to the Google+ API. If you’re just starting with Google+ APIs, this is a great way to easily experiment with the API.

As always, feel free to ask questions in the comments or by mentioning +Gregory Class (Gus) on Google+.