2

I get credentials using code

 static string[] Scopes = { "https://www.googleapis.com/auth/userinfo.email" };

    private static UserCredential GenerateCredential()
    {
        UserCredential credential;
        using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
        {
            // The file token.json stores the user's access and refresh tokens, and is created
            // automatically when the authorization flow completes for the first time.
            string credPath = "token.json";
            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(credPath, true)).Result;
            Console.WriteLine("Credential file saved to: " + credPath);
        }

        return credential;
    }

How to get email from this credential? I've tried code

private string GetEmailFromCredentials(UserCredential credential)
    {
        var plusService = new PlusService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "My Application",
        });

        var me = plusService.People.Get("me").Execute();
        var useremail = me.Emails.FirstOrDefault().Value;

        return useremail;
    }

but it looks like that People.Get("me") is not possibe anymore. I'm getting error "Google.Apis.Requests.RequestError Legacy People API has not been used in project 618254727025 before or it is disabled"

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449

5 Answers5

3

solution is to get access token and try https://www.googleapis.com/oauth2/v2/userinfo?access_token=

1
  • In your scopes variable. Try and just use the value "email" not the full https address. Scope keywords in the web link are separated by spaces. Here is a way that I do this to obtain the scopes: profile email openid.

  • To test this approach, you can manually paste the below weblink into a browser after obtaining the access code: https://www.googleapis.com/oauth2/v2/userinfo?access_token=[PASTE ACCESS CODE HERE]&[PASTE VALUE FROM THE BELOW VARIABLE authorizationRequest HERE]

  • fyi: I was ammending the demonstration code available: https://github.com/googlesamples/oauth-apps-for-windows.

     // Creates the OAuth 2.0 authorization request.
     string authorizationRequest = string.Format("{0}?response_type=code&scope=openid%20profile%20email&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
         authorizationEndpoint,
         System.Uri.EscapeDataString(redirectURI),
         clientID,
         state,
         code_challenge,
         code_challenge_method);
    
0

You can use the users.getprofile it will return the email address of the user who is currently authenticated.

request

 var service = new GmailService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "My Application",
        });

  var user = service.Users.GetProfile("me").Execute;

response

{
  "emailAddress": "xxxx1@gmail.com",
  "messagesTotal": 8394,
  "threadsTotal": 1494,
  "historyId": "605503"
}

People me

The correct usage of people.get is "people/me"

 var request = plusService.People.Get("people/me")
 request.PersonFields("emailAddresses");
 var response = request.Execute();
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • thanks for your answer... unfortunately I can't use GetProfile here, just because I don't want to ask users to provide access to their gmail. It will be weird solution in my case... I only want to check that user in my applicate has access to some google account and get his email – Дмитрий Регент Jun 27 '20 at 20:39
  • but I understand that maybe all my schema is wrong... oauth is designed to not sending login – Дмитрий Регент Jun 27 '20 at 21:22
0

I have been stuck on this issue for several days. And finally, thanks to this link (Check if user is already logged in), I learned that the parameter input, "user", to be the key issue. This "user" should be the windows login user (you can use Enviroment.Username), not the programmer or APP user. The GoogleWebAuthorizationBroker.AuthorizeAsync uses this username to save its credential in the location:

C:\Users[username]\AppData\Roaming\Google.Apis.Auth\Google.Apis.Auth.OAuth2.Responses.TokenResponse-[username]

(something like this). So if you feed "user" to AuthorizeAsync, the credential saving could be a problem, and your app will hang or lag seriously. And, later when you want to use the cred file to get userinfo and email, it will be problematic (lag seriously). In my case, user info will be all missing, leaving only an email address. Also, you have to include the required two scopes: "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile". Hope these helps.

Alisettar Huseynli
  • 944
  • 1
  • 11
  • 24
nips
  • 1
  • 2
  • 1
    For more details, the code for getting the email is: Oauth2Service oauthService = new Oauth2Service(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "your app name" }); var userinfo = oauthService.Userinfo.Get().ExecuteAsync().Result; var useremail = userinfo.Email; – nips Sep 22 '21 at 07:44
0
  1. Add 'https://www.googleapis.com/auth/userinfo.email' in scopes.
  2. In callback you will code. Get tokens json from this code using oauth2Client.
  3. This json contains id_token which is basically a jwt token, parse it u will get email.
Pankaj Shinde
  • 3,361
  • 2
  • 35
  • 44