Morfinismo
Morfinismo

Reputation: 5253

Picture missing from credential token with GSI

I have been using the new GIS library with the One Tap UX. I have followed all the steps outlined in the setup guide and the authentication works as expected, in fact I like the new flow; Nonetheless I am experiencing a very peculiar issue. For some reason, the picture property is missing from the credential response.

A couple of things to note are:

  1. This is an internal application, which means it is only being used by the google workspace users of the respective domain.
  2. This happens with all users whose profile picture is set using the Admin Directory API.

What I have in the front end is the following:

  const promptParent = "signInBox";
  const gsiInitializeConfig = {
    client_id: '4xxyy55zzz.apps.googleusercontent.com',
    callback: handleCredentialResponse,
    prompt_parent_id: promptParent,
    auto_select: true,
    cancel_on_tap_outside: false
  };
  let idClient;   

  const doSignIn = ()=>{
    idClient = google.accounts;
    idClient.id.initialize(gsiInitializeConfig);
    idClient.id.prompt();
  }

  const handleCredentialResponse = (response)=>{
    const {credential} = response;
    //send idToken to the backend for verification
  });

When the DOMContent is loaded, I programatically invoke the doSignIn function. And the one tap shows and it works great. It returns the idToken which then I send to the backend for verification. In the backend I am using express and I have the following:

  const token = getTokenFromBody();
  if(!token){ return unauthenticated(res); }
  const auth2Client = new OAuth2Client(GOOGLE_CLIENT_ID);
  const ticket = await auth2Client.verifyIdToken({
    audience: GOOGLE_CLIENT_ID,
    idToken: token
  }).catch(error=>{
    console.error(`Failed to verify google id token: ${error}`);
    unauthorized(res, "Invalid grant");
  });
  if(!ticket){ return; }
  const ticketPayload = ticket.getPayload();
  console.log("ticketPayload", JSON.stringify(ticketPayload));

The logged object for the ticketPayload above looks like this:

{
  iss: "https://accounts.google.com",
  nbf: 1378,
  aud: "44xxyy55zz.apps.googleusercontent.com",
  sub: "1559234417",
  hd: "domain.com",
  email: "[email protected]",
  email_verified: true,
  azp: "44xxyy55zz.apps.googleusercontent.com",
  name: "User Name",
  given_name: "User",
  family_name: "Name",
  iat: 1664828678,
  exp: 1664832278,
  jti: "f0549d2544c905sadfcbc13110"
}

That is the response for all the users in the domain, however, for my user, whose photo was set using the page "https://myaccount.google.com", the response is the following:

{
  iss: "https://accounts.google.com",
  nbf: 1378,
  aud: "44xxyy55zz.apps.googleusercontent.com",
  sub: "1559234417",
  hd: "domain.com",
  email: "[email protected]",
  email_verified: true,
  azp: "44xxyy55zz.apps.googleusercontent.com",
  name: "User Name",
  picture: "https://lh3.googleusercontent.com/a-/N5pZpE-zbJUg3=s96-c", // <-----!!!
  given_name: "User",
  family_name: "Name",
  iat: 1664828678,
  exp: 1664832278,
  jti: "f0549d2544c905sadfcbc13110"
}

In comparisson with the old google sign in library, this behavior is different. How can I get the picture property for all users in the domain?

Upvotes: 2

Views: 303

Answers (1)

Morfinismo
Morfinismo

Reputation: 5253

I reached out to Google Workspace support were they educated me with the following:

Admin-set user profile picutres (either set by an Admin via the Admin Console itself, or by the Admin SDK API call) are private and are not returned in the credential response of the Google Sign In flow.

The reason for that is that when an administrator sets a profile photo to a user's account, the photo becomes visible only to users in the organization and to external users they use Google Chat with. In contrast, (and only if users are allowed to manage their own profile photo) user-set photos are public by default. That is explained under the "Where a user's photo appears section of this support article.

This behavior cannot be changed for privacy reasons. An admin-set photo is neither public information, nor is set by the user, hence is not available in the token.


Although the solution provided makes sense, there is something that I feel is wrong. The fact that the old google sign in library never presented this behavior makes me feel that way. Why should the new sign in library present this behavior now? It is really absurd.

Upvotes: 3

Related Questions