Chadz001
Chadz001

Reputation: 83

Google Identity Service - How Obtain Profile / Email Information From Authenticated user

I'm porting over some existing js code authenticating with the google cloud platform (as they are migrating to a new set of libraries).

(migration guide: https://developers.google.com/identity/oauth2/web/guides/migration-to-gis)

I'm struggling with getting a hold of the player's profile (to obtain their email).

The old approach would be along the lines of this (but as it says, it is now deprecated - I've been reading the new docs but it mostly surrounds getting authorized/authenticate and not the follow on from that): https://developers.google.com/identity/sign-in/web/people

e.g.

var profile = auth2.currentUser.get().getBasicProfile();
var email = profile.getEmail();

In my new code I've have the access token, via the new approach:

    client_id: vm.clientId,
    scope: SCOPE,
    callback: (tokenResponse) => {
        if (tokenResponse && tokenResponse.access_token) {
            access_token = tokenResponse.access_token;

            // HERE??? HOW DO I GET THE PROFILE?

        }
    }
})

(largely taken from https://developers.google.com/identity/oauth2/web/guides/use-token-model)

I've seen this mentioned elsewhere but it doesn't work in my situation at least:

gapi.client.oauth2.userinfo.get().execute(function (resp) {
   console.log(resp);
})

(How to get profile information from Google Identity Services?)

I've read via the migration guide: 'Instead, use direct references to credential sub-fields in the new JWT CredentialResponse object to work with user profile data.' but don't know how to get this Credentialresponse? (https://developers.google.com/identity/gsi/web/guides/migration#token_response)


Upvotes: 5

Views: 2992

Answers (2)

Rahul Sharma
Rahul Sharma

Reputation: 8312

You can follow these steps that I had to undertake to achieve the entire flow using Javascript.

First create a button that will hold the HTML element:

<button id="btnGoogleSignIn" style="border:none;background: none;"> </button>

You can then use the below script and associated functions in which I am getting the JWT token from Google and then decoding it to get the required information out like email address etc. Note that I am calling the onSignInGSI as callback on the button initialization.

<script>  
    function decodeJwtResponseFromGoogleAPI(token) {
            let base64Url = token.split('.')[1]
            let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
            let jsonPayload = 
           decodeURIComponent(atob(base64).split('').map(function (c) {
                return '%' + ('00' + 
           c.charCodeAt(0).toString(16)).slice(-2);
            }).join(''));
            return JSON.parse(jsonPayload)
        }

    function onSignInGSI(response) {
        //console.log(response)
        responsePayload = decodeJwtResponseFromGoogleAPI(response.credential);
        console.log("ID: " + responsePayload.sub);
        console.log('Full Name: ' + responsePayload.name);
        console.log('Given Name: ' + responsePayload.given_name);
        console.log('Family Name: ' + responsePayload.family_name);
        console.log("Image URL: " + responsePayload.picture);
        console.log("Email: " + responsePayload.email);
    }

    window.onload = function () {

        google.accounts.id.initialize({
            client_id: client_id,
            context: 'signin',
            callback: onSignInGSI
        });

        google.accounts.id.prompt();
        
        google.accounts.id.renderButton(document.getElementById("btnGoogleSignIn"), 
        {
            type: "standard",
            text: "signin_with",
            logo_alignment: "left",
            width: 375
        });
    };
</script>
<script src="https://accounts.google.com/gsi/client" async defer></script>

Upvotes: 7

Chadz001
Chadz001

Reputation: 83

Adding a function like this works in my situation:

function getUserProfileData(accessToken) {
    let promise = new Promise(function(resolve, reject) {
        let request = new XMLHttpRequest();
        const url = `https://www.googleapis.com/oauth2/v3/userinfo`;
        request.addEventListener("loadend", function() {
            const response = JSON.parse(this.responseText);
            if (this.status === 200) {
                resolve(response);
            } else {
                reject(this, response);
            }
        });
        request.open("GET", url, true);
        request.setRequestHeader('Authorization', `Bearer ${accessToken}`);
        request.send();
    });

    promise.then(function(response) {
        var email = response.email;
    }, function(errorMessage) {
        // TODO: print error
    });
} 

This returns a json that contains the following properties:

  • email
  • email_verified
  • family_name
  • given_name
  • hd
  • name
  • picture
  • sub

Upvotes: 3

Related Questions