Reputation: 83
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
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
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:
Upvotes: 3