30

I am using OAuth to access Gmail with dotNetOAuth. How can I force Google to return user's email address as part of callback after authorization?

By default, Google OAuth callback only returns the token secret and access tokens.

Khash
  • 2,500
  • 4
  • 30
  • 56
  • 1
    Did you find out which API call you can use to get the user's email address? – Christian Davén Sep 08 '10 at 14:25
  • 2
    No. Moreover, due to different implementations of OAuth on different providers, we decided to drop the requirement and implement a business workaround. It just reminds me of the quote "The best thing about standards is there are lots of them" – Khash Nov 10 '10 at 09:12

7 Answers7

66

First you need to add the following scope (https://www.googleapis.com/auth/userinfo.email) to your oauth request.

After you're back to your app from Google and you have your access token, you can make a request using the access token to https://www.googleapis.com/userinfo/email?alt=json. This will return the email address. More info at http://sites.google.com/site/oauthgoog/Home/emaildisplayscope

Mark
  • 473
  • 6
  • 7
mergoc
  • 661
  • 5
  • 4
  • 2
    This link may help anyone who struggles with signing Google API requests (you need to add Authorization header): http://code.google.com/apis/accounts/docs/OAuth_ref.html#SigningOAuth – Pawel Lesnikowski Jun 15 '11 at 16:40
  • 1
    This wasn't working for me. If it doesn't for you either, you can also connect to Google Contacts in (addition to connecting with Gmail) to get your email address. See: http://stackoverflow.com/questions/6970794/is-there-a-way-to-get-your-email-address-after-authenticating-with-gmail-using-oa – Joe Aug 09 '11 at 00:47
  • Adding userinfo.email scope to my outh request worked fine for me. After that I was able to retrieve email from oauth response. – ftassi Aug 15 '13 at 09:04
10
For getting the Email Id, you need to add the scope "https://wwww.googleapis.com/auth/userinfo.email"

Then you will get id_token in the response.

Response={
   "access_token" : "ya29.eAG__HY8KahJZN9VmangoliaV-Jn7hLtestkeys",
   "token_type" : "Bearer",
   "expires_in" : 3600,
   "id_token" : "id_token_from_server",
   "refresh_token" : "1/GIHTAdMo6zLVKCqNbA"
 }

Then use this id_token as below POST request:

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=id_token_from_server

And you will get response like below:

Response={
 "issuer": "accounts.google.com",
 "issued_to": "80780.apps.googleusercontent.com",
 "audience": "8078909.apps.googleusercontent.com",
 "user_id": "1118976557884",
 "expires_in": 3598,
 "issued_at": 1456353,
 "email": "emailId@gmail.com",
 "email_verified": true
}

Make sure you add "www" in the APIs as shown above...
Naren
  • 2,706
  • 1
  • 21
  • 15
9

OAuth doesn't provide a facility for extra parameters during an OAuth handshake, so I don't think you can force Google to supply it. There is likely a Google API however that you can use your OAuth access token to call to fetch the email address after the handshake, however.

Andrew Arnott
  • 80,040
  • 26
  • 132
  • 171
2

Here's a c# function for when you have pre-authorized the request as detailed above:

        private void FetchUsersEmail(token)
        {
            var emailRequest = @"https://www.googleapis.com/userinfo/email?alt=json&access_token=" + token;
            // Create a request for the URL.        
            var request = WebRequest.Create(emailRequest);
            // Get the response.
            var response = (HttpWebResponse) request.GetResponse();
            // Get the stream containing content returned by the server.
            var dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            var reader = new StreamReader(dataStream);
            // Read the content. 
            var jsonString = reader.ReadToEnd();
            // Cleanup the streams and the response.
            reader.Close();
            dataStream.Close();
            response.Close();

            dynamic json = JValue.Parse(jsonString);
            var currentGoogleEmail = json.data.email;
        }

(JValue is part of JSON.Net)

jenson-button-event
  • 18,101
  • 11
  • 89
  • 155
2

request OAuth scope to include the "Email Display Scope" https://www.googleapis.com/auth/userinfo.email

scope="http://www.google.com/m8/feeds/ https://www.googleapis.com/auth/userinfo.email"

Then use REST API like Hammock to get address

            RestClient client = new RestClient
            {
                Authority = "https://www.googleapis.com",
            };

            RestRequest request = new RestRequest
            {
                Path = "userinfo/email?alt=json",
                Credentials = OAuthCredentials.ForProtectedResource(
                     this.requestSettings.ConsumerKey,
                     this.requestSettings.ConsumerSecret,
                     this.requestSettings.Token,
                     this.requestSettings.TokenSecret)
            };

            var response = client.Request(request);
Paulius Zaliaduonis
  • 5,059
  • 3
  • 28
  • 23
  • Also look at https://sites.google.com/site/oauthgoog/Home/emaildisplayscope and verify your tokens on http://googlecodesamples.com/oauth_playground/ – Paulius Zaliaduonis Oct 13 '11 at 11:19
1

In php, apiOauth2Service.php class provides methods to access logged in user info. For this you can use userinfo->get() method. Make sure you also use scope https://www.googleapis.com/auth/userinfo.email.

This will work with same access token. Also you should try looking in other APIs for similar kind of information in return. This is much easier to look through oAuth_playground >> http://code.google.com/apis/explorer/

Manish
  • 39
  • 1
  • 8
0

If you request the userinfo.email scope, Google returns an id_token along with the access_token.

The id_token can be unencrypted to provide the user's email address, at www.googleapis.com?/oauth2/v1/tokeninfo?id_token=IDTOKENHERE

More information here: https://developers.google.com/accounts/docs/OAuth2Login

Lee
  • 2,610
  • 5
  • 29
  • 36