7

We have an application that relies upon Google to authenticate its users against our google apps account and then do some serverside verification and group lookups.

Recently google changed the name of the object that held the access_token variable which we require to authenticate. In the docs (https://developers.google.com/identity/sign-in/web/reference#googleusergetbasicprofile) it says that access_token is available from the getAuthResponse() method, however when i use this it comes back as undefined. Inspecting the object after console.log() reveals all the other fields mentioned except access_token. I'm worried that Google will change the object again in the future and leave us without our application. Here is the code.

<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<meta name="google-signin-client_id" content="XXX.apps.googleusercontent.com">
<script>
    //This happens after the user has authenticated with Google and has been passed
    //back to the page
        function onSignIn(googleUser) {
            //Check to see whether the user is trying to sign out.
            if (window.location.href.indexOf("signOut=1") !== -1) {
                //Sign them out of the application.
                signOut();
                //redirect them to the same page, without the signOut query string so they can log back in if want
                window.location.href='googlesigninform.html'
                return false;
            }
            //Grab the token, access token and email.
            var _id = googleUser.getAuthResponse().id_token; //This works
            var _accessToken = googleUser.Ka.access_token; //This works but changed from googleUser.B.access_token
            var profile = googleUser.getBasicProfile(); //Works
            console.log(googleUser.access_token); //Undefined
            console.log(googleUser.getAuthResponse().access_token);//Undefined
            //Make a post request to the API
            makePostRequest(_id, _accessToken, profile.getEmail());
        }

What is the correct way to access the access_token variable?

2
  • Is this that stupid of a question that no-one replies? Commented Sep 13, 2015 at 22:15
  • Happened again last night. The raw object once again changed names and broke our applications. Commented Sep 15, 2015 at 16:00

5 Answers 5

4
+25

If you need to use access token you are using the wrong type of google signin flow. You should follow this page: https://developers.google.com/identity/sign-in/web/server-side-flow

What you did implement is google Sign-In to identify users (https://developers.google.com/identity/sign-in/web/)

Which only provides a unique id per user because it is meant to authenticate the user for your own service and not to give an access token to use for other Google services later on.

4

I believe your problem is that your application is lacking the necessary google-signin-scope.

To answer your question i created an app from the ground using the Google Developer Console. The application is very simple like the one this this tutorial.

The entire application consists of a simple HTML that loads the google API and has a callback called onSignIn (like yours).

Here's the entide code of the application:

<html lang="en">

<head>
  <meta name="google-signin-scope" content="profile email">
  <meta name="google-signin-client_id" content="PLACE_YOUR_ID_HERE.apps.googleusercontent.com">
  <script src="https://apis.google.com/js/platform.js" async defer></script>
</head>

<body>
  <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
  <script>
    function onSignIn(googleUser) {

      var response = googleUser.getAuthResponse(),
        idToken = response['id_token'],
        accessToken = response['access_token'];

      console.dir('id token: ' + idToken);
      console.dir('access token: ' + accessToken);
    }
  </script>
</body>

</html>

As you can see, the difference between my app and yours is that yours is lacking the first META attribute.

2
  • Well this does work. I'm just concerned that this isn't necessarily correct as per Bas answer above. I will look into it today and figure it out. Thanks Commented Sep 22, 2015 at 16:43
  • The api document developers.google.com/identity/sign-in/web/… specifies that it returns the access_token. The answer by @Romulo explains why the result of access_token is undefined. I managed to reproduce the problem when I intentionally left out the scope. I think this should be the accepted answer. Commented Feb 16, 2016 at 7:30
1

Well i have a hack work around that gets the access_token from the variable.

function findAccessToken(googleUser) {
            var returnValue;
            Object.getOwnPropertyNames(googleUser).forEach(function (val, idx, array) {
                console.log(val + ' -> ' + googleUser[val]);
                Object.getOwnPropertyNames(googleUser[val]).forEach(function (vals, idxs, arrays) {
                    if (vals === "access_token") {
                        console.log("true");
                        returnValue = googleUser[val][vals];
                    }
                });

            });
            return returnValue;
        }

Surely this can't be the most elegant solution. If someone could point in the righter direction that would be good.

0

Here is the code for sign in using google.

  <html lang="en">
  <head>
    <meta name="google-signin-scope" content="profile email">
    <meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
    <script src="https://apis.google.com/js/platform.js" async defer></script>
  </head>
  <body>
    <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
    <script>
      function onSignIn(googleUser) {
        // Useful data for your client-side scripts:
        var profile = googleUser.getBasicProfile();
        console.log("ID: " + profile.getId()); // Don't send this directly to your server!
        console.log("Name: " + profile.getName());
        console.log("Image URL: " + profile.getImageUrl());
        console.log("Email: " + profile.getEmail());

        // The ID token you need to pass to your backend:
        var id_token = googleUser.getAuthResponse().id_token;
        console.log("ID Token: " + id_token);
      };
    </script>
  </body>
</html>
0

Try this var _access_token = GoogleUser.getAuthResponse().access_token

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.