Google+ Tricks: Hacking the Sign-in button behavior

Before continuing, I want to emphasize that this is not a best practice. You should be using the Google+ Sign-in Button as intended. Signing in to an application with Google should do just that – if you sign out of Google, you then are signed out of the associated sites.  It can be a little tricky and may not work the way you expect it to at first but this is the behavior that you get already on the internet from Google. Google keeps you signed in for good reasons and so when your site behaves consistently, that’s probably how users expect your site to behave –  to do otherwise as described in this post is to make your specific site inconsistent.

If you really, really, really, want to do this, however, there is nothing stopping you from changing the way your site behaves – *puts on lawyer hat* at least from a purely technical perspective. I have no idea as to whether this will work forever or will always conform to policies related to the sign-in button – code is provided as-is and I claim no responsibility for what you do with it. I will also emphasize that this in no way enhances your security. In many ways, these alternative behaviors share a common theme which helps to explain why this really does nothing for security: your site will just be pretending not to know that the user is signed in until they perform an action on the site related to the sign-in button.

While discussing each approach, I will try and stretch my imagination to explain why you might want to do this and will also tell you why you probably don’t want to do this. I have created mocks for each of the approaches that demonstrate the behavior but the code used in the mocks is more quick-and-dirty so it shouldn’t be used.

Method 1: The Heise approach

I recently was pointed to an article by on Heise online about “two clicks for privacy” and this pretty much inspired this approach.  What you do is create an overlay image for the sign-in button that will trigger explicit render for the sign-in button.

The following diagram illustrates what happens:

This works as follows:

1.) The user comes to your page and sees the grayed out image:

2.) Upon clicking the image, explicit render is called on the sign-in button.  This causes the explicit render for the sign-in button to occur and the sign-in button renders as follows…

See it in action here: Demo: Hacking the Google+ Sign-in Button behavior with the Heise approach

This approach has a number of issues, most notably the behavior for the button is different when the user is signed out from Google from when the user is signed in.  Additionally, the user needs to click twice – which is really awkward.

The benefit of this approach is that it lets you be a lazy programmer when your site does something similar to the JavaScript quickstart where things automatically happen when the user signs in to your site. This behaves this way because it delays the explicit render of the sign-in button until the first click, preventing the sign-in callback from being triggered.

Approach 2: The “doubletap”

This is my favorite approach by far because it behaves the closest to the way that I think developers want the sign-in button to work when they ask about disabling the button from automatically triggering. What you do is render the sign-in button but only show it after you have tracked a click within the span containing the sign-in div.  The following image tries to summarize what’s going on visually:

The following code shows how this works from within the sign-in callback:

  var tapCount = 0;
  function onSigninCallbackVanilla(authResponse){
    // Used in a basic case where the button is rendered
    token = authResponse.access_token;
    if (authResponse.error == undefined){
      tapCount++;
      $('#disconnect').show();
      if (tapCount > 1){
        $("#signinButton").hide();
      }
    }
  }

And from within the sign-in button:

      <span id="signinButton" onClick="tapCount++;">
        <span
          class="g-signin"
          data-callback="onSigninCallbackVanilla"
          data-clientid="YOUR_CLIENT_ID"
          data-cookiepolicy="single_host_origin"
          data-requestvisibleactions="http://schemas.google.com/AddActivity"
          data-theme="dark"
          data-scope="https://www.googleapis.com/auth/plus.login">
        </span>
      </span>

Note that this is purely a way of pretending that the UX behavior is different from how it actually is. It works though at showing the “click sign-in to sign-in experience”, and even pops up the sign-in dialog for a second because it retriggers the callback before hiding the button. You can see the “doubletap” sign-in behavior on this demo page.

Approach 3: “Cookiedrop”

This is another interesting way of doing things: sign out from the site.  What you do for this is to set a cookie on the user’s client indicating that the user is signed in to the site (for simplicity, lets call this “enrolled”) and because of this, you want them to automatically be “enrolled” into your site. I want to stop for a second here and again say that the way to get the desired behavior is to set the cookie after your user is  signed-out (“unenrolled”) as opposed to enrolle.  Using this approach is done to address the following scenario:

  1. User opens different browser
  2. User checks their GMail (signs in to Google)
  3. User visits your site
  4. User unexpectedly gets signed in automatically

If you are testing for the lack of a cookie to prevent the sign-in button from hiding, your user will not automatically be enrolled on your site when reaching it from an authenticated session.

Visually, the following diagram roughly shows how this would work:

 

The following code shows how the “enrolled” cookie is set, indicating the user will not see sign-in when reaching the site.

  // Simulate "enrolled" for the site: happens once the user accesses site
  function cookieAdd(){
    document.cookie = 'enrolled=1;expires=0';
  }

The following code shows how the “not enrolled” cookie is set using JavaScript, indicating the Sign in button is simulated:

  // Simulate "not enrolled" for the site
  function cookieDrop(){
    document.cookie = 'enrolled=0';
    $('#signinButton').show();
    $('#signedin').hide();
  }

The code for triggering the sign-in button is essentially the same as the doubletap approach.  You can see a demo of the cookiedrop here. The code is done in JavaScript, but I would be more keen on setting the cookie on the server after the user has actually been placed inside your site.

Kinda lame, I know.  However, you can use this approach to simulate logging out of your site. The advantage to this approach is that it is the user can get the experience they expect when visiting your site, as seen in the previous approach, but additionally you can simulate the “stay signed in” behavior that is performed using cookies. As it exists, the sign-in flow becomes much more complicated because you are independently managing two separate states: the state for your site and the state for Google. That said, you could do something even more complicated and avoid the sign-in callback from getting triggered by using the cookie state for triggering the rendering of the sign-in button – very confusing.

Conclusions

As much as I would like to endorse one of these approaches as the solution to how you should change the sign-in behavior  – none of these solutions feels like the “right” way to do things. Hacking the experience that you get from the sign-in button like this is not an effective approach but is instead a way of simulating it, not unlike saving a screenshot of your desktop icons from a previous arrangement and then moving them all into a folder, and finally setting the desktop background to the saved screenshot. It may seem like it’s what you want, but I’m guessing it really isn’t what is really the right thing for your user or your site and could potentially cause issues.

If you’re rolling your own approach to hacking the behavior of the sign-in button, you should be very careful how you do it because there are a number of ways that things can go wrong and it can give you and your users the false sense of security that a malicious user would not be able to access an account even though they are still signed in to Google. Please, feel free to share with me if you have a secure approach to doing this or fork my sign-in behaviors GitHub project and put in a pull request with your suggested changes.

There is a safe approach to prevent your user’s sensitive information from appearing: forcing reauthorization using your site’s specific credentials.  Google does this when users reach certain areas of Google such as the accounts recovery options page and issued auth subtokens page. This is only realistically practical in extreme cases such a banking sites where you REALLY don’t want a passer-by to access a user’s data or a part of your site.