stormpath / idsite-src

Project source for Stormpath's default production ID Site
Apache License 2.0
15 stars 55 forks source link

Login via Google should request profile scope in addition to email scope #31

Open george-hawkins-work opened 8 years ago

george-hawkins-work commented 8 years ago

When going via Google for social login just the email scope is requested - see login.js:115.

This means you just get the email address for the user but you don't get their name - so the corresponding account created in Stormpath ends up with the name "NOT_PROVIDED NOT_PROVIDED", i.e. "NOT_PROVIDED" for both first and last name.

If you select the scope profile, in addition to email, then you will also get the user's name and the https://www.googleapis.com/userinfo/v2/me request will respond with something like:

{
  "family_name": "Hawkins", 
  "name": "George Hawkins", 
  "picture": "https://lh4.googleusercontent.com/-XqMkLM9LOHU/AAAAAAAAAAI/AAAAAAAAAAs/aesMnjBLHs4/photo.jpg", 
  "locale": "en", 
  "email": "george.hawkins@foo.com", 
  "given_name": "George", 
  "id": "1234567", 
  "hd": "foo.com", 
  "verified_email": true
}

Note: the above was produced via the very nice Google OAuth 2.0 Playground.

george-hawkins-work commented 8 years ago

Having said that... despite only seeing a reference to email in login.js it does look like two scopes are being requested in the Google consent page that one sees: stormpath-scopes It would be really nice if Google included the scope names in the underlying HTML to make clear what's being requested but they don't.

Anyway even if profile is also implicitly being selected as a scope I still end up with user accounts with the name "NOT_PROVIDED NOT_PROVIDED" :disappointed:

Maybe the family_name and given_name fields in the data from Google are not being properly processed?

george-hawkins-work commented 8 years ago

If I hack the following into one of my Java servlets in my web app:

Account account = AccountResolver.INSTANCE.getAccount(request);
ProviderData data = account.getProviderData();

if (data instanceof GoogleProviderData) {
    GoogleProviderData googleData = (GoogleProviderData)data;

    System.err.format("Try: \"curl -i -H 'Authorization: Bearer %s' https://www.googleapis.com/userinfo/v2/me\"%n", googleData.getAccessToken());
}

And then trigger a request that causes this code to be hit then I see something like this on standard error:

Try: "curl -i -H 'Authorization: Bearer XYZ' https://www.googleapis.com/userinfo/v2/me"

If I then do try that curl request I get back something like this:

{
 "id": "105742200934306200174",
 "email": "george.hawkins@foo.com",
 "verified_email": true,
 "name": "",
 "given_name": "",
 "family_name": "",
 "picture": "https://lh4.googleusercontent.com/-XqMkLM9LOHU/AAAAAAAAAAI/AAAAAAAAAAs/aesMnjBLHs4/photo.jpg",
 "hd": "foo.com"
}

So it seems clear just email scope was requested.

robertjd commented 8 years ago

Hello George, thank you for reporting this.

The email scope should give you access to the basic profile information of name, given name, etc. This is a change that they recently made. I can confirm this by using the OAuth 2.0 Playground. Can you try the same, requesting only the email scope?

When I use our default ID Site application, I receive an account object that has the name fields populated. At the moment I'm not able to reproduce a situation where I get NOT_PROVIDED for the name fields.

george-hawkins-work commented 8 years ago

Hi Robert -- thanks for getting back on this. I can confirm that I still see this issue. Here are screen shots that show the problem.

1. If I request only email scope I don't get family or given name. As you can see the empty string, i.e. "", is displayed for both: email-only

2. If I request only profile scope I do get family and given name (but not email): profile-only

I just made these screen shots just now - so this is a current issue. Note: the Playground web app seems to have a bug - if I e.g. try only profile scope and then go back, expand step 1, unselect that scope and select email scope and then redo steps 2 and 3 it seems to incorrectly remember profile scope, i.e. I get results as if both profile and email scope were selected. Only if I hit the big X button above all the steps does it really start again from scratch.

And here is the consequences I see, i.e. NOT_PROVIDED in the name fields: not-provided

Sorry for blacking out so much stuff in the screen shots - I erred on the side of caution as to what might or might not be meant to be public.

george-hawkins-work commented 8 years ago

Always failing or always succeeding is good - but inconsistent behavior is horrible.

@robertjd - I can confirm that I still see the above described behavior for some users. I cleared out all accounts associated with my application's Google directory and got two users to login via the ID site using social login. This is the result:

not-provided

As you can see I now appear with a first and last name (even though previously you can see this didn't happen). But the other user (who logged in around the same time in just the same manner) however shows the problem covered by this issue, i.e. shows up with first and last name being NOT_PROVIDED.

Even odder I can confirm that I continue to just get an email address for myself (but no name information) if I use the Google OAuth 2.0 Playground (as described previously) and just request email scope - to get name and email information I have to request scopes profile and email.

george-hawkins-work commented 8 years ago

Hi @robertjd - I've put a project up on Github that covers this issue (and a couple of other problems I found while experimenting with the ID site). Please see the ID site section of the README.

robertjd commented 8 years ago

Hello @george-hawkins-aa - thank you for all the detail!

What confuses me is that I still can't reproduce the situation where email scope does not provide the full account names, I always get those back. For sanity, here is a screencast of the workflow I am using in the Oauth playground:

http://recordit.co/7ZacIoLxP8

Can you tell me if this is the same flow you were following?

Note that before that screencast, I removed the oauth2 playground from my list of authenticated applications, and hit the "X" in the top of the window to ensure that there were remaining access tokens for this application. I also revoked access after this screencast, so that the tokens you see in the video are no longer valid.

While I cannot reproduce the situation, it does seem that changing the request scope value in the ID Site application to be email profile is working fine. I'll want to test a bit more, but it probably makes sense to just switch to this scope value.

Thanks again for the help!

robertjd commented 8 years ago

One more thing: I just learned that it's possible for a google account to exist without a first name or last name defined. Do you think that might be the case for some of the accounts where you are seeing NOT_PROVIDED?

george-hawkins-work commented 8 years ago

Hi @robertjd - I went through exactly the same steps as you did and also did a screen recording. I'm a bit paranoid about including something here with so many IDs (most or all or which I'm sure are of zero long term relevance if as you say one revokes the relevant authorization afterwards) so I'll just include a screen shot of the final frame here with various bits blacked out: image As you can see there's only the email address and no given or family name information here. If you want the full video to double check I'm not doing something weird (e.g. selecting the wrong or an old version of the relevant API) then ask Micah Silverman for my email address and I'll send the video to you rather than post it here in public.

As to your question about whether or not the involved accounts have first or last names - they definitely do have these values - and these values can be retrieved in the OAuth playground if one includes the profile scope.

robertjd commented 8 years ago

Hello @george-hawkins-aa ! I forgot to update this thread. We have decided to update this project, we will use email profile by default. Stay tuned for our next release. Thanks again for all the help!

vlads-copart commented 7 years ago

Still does not work as stormpath.js only seems to be passing 'email' permission when constructing google url ? SDK is not using properties google.scope

vlads-copart commented 7 years ago

Is there a workaround for now?