google / google-api-javascript-client

Google APIs Client Library for browser JavaScript, aka gapi.
Apache License 2.0
3.22k stars 1.06k forks source link

Missing profile information from GSuite account. #422

Open phyllisstein opened 6 years ago

phyllisstein commented 6 years ago

Hey folks! This is not wildly urgent, but I've been working on implementing authentication through Google and I'm having some trouble grabbing the profile-scope data for a GSuite domain. I'm not sure whether the issue is that GSuite or my application is misconfigured, so I was hoping you could provide some troubleshooting guidance.

The flow in the app is this. On the frontend, I call gapi.auth2.authorize to retrieve an ID token and POST it to my backend:

gapi.auth2.authorize(
  {
    client_id: '...',
    hosted_domain: 'ignota.media',
    response_type: 'id_token',
    scope: 'email profile',
  },
  (response: any) => {
    if (response.error) {
      return
    }

    this.props.onSignInGoogleAccount(response.id_token)
  },
)

On the backend, I pass the ID token to https://www.googleapis.com/oauth2/v3/tokeninfo to validate it:

def token_info
  @token_info ||= begin
                    ti = conn.get '/oauth2/v3/tokeninfo', id_token: id_token
                    body = JSON.parse(ti.body).with_indifferent_access
                    raise ArgumentError, 'Invalid hosted domain.' unless body[:hd] == 'ignota.media'
                    body
                  end
end

After walking through the signup flow, I get a valid token back---but according to the tokeninfo endpoint, it only includes email and email_verified alongside the usual JWT claims:

{
 "azp": "...",
 "aud": "...",
 "sub": "108825333075518568948",
 "hd": "ignota.media",
 "email": "d@ignota.media",
 "email_verified": "true",
 "exp": "1523788138",
 "iss": "accounts.google.com",
 "jti": "1f171bc654823ed4170a624fc867d97e24af88da",
 "iat": "1523784538",
 "alg": "RS256",
 "kid": "3b547886ff85a3428df4f61db73c1c23982a928e"
}

The documentation at https://developers.google.com/identity/sign-in/web/backend-auth seems to suggest that GETting the tokeninfo endpoint should include name, picture, and locale as well, but try as I may I can't get them into the JWT payload. My GSuite account should---I believe---have all three configured through the "Users" panel of the admin interface.

Any idea what I might be doing wrong?

dylanscott commented 6 years ago

I was running into this too, and found that I had to add permission to the response_type, and openid to the scope in the authorize call.

phyllisstein commented 6 years ago

@dylanscott That did the trick! Thanks so much for sharing your solution. I'mma leave this open as a nudge to update the docs, but it seems to work great.

antony commented 5 years ago

Found this trying to diagnose an error which occurred as of today, with previously working code.

Because it might be helpful to people who find this issue in the future , as of today, Google's auth response now only includes a picture url if you have explicitly set a profile picture.