在 C# 中使用 google OAuth2 后如何获取电子邮件?

Posted

技术标签:

【中文标题】在 C# 中使用 google OAuth2 后如何获取电子邮件?【英文标题】:how to get email after using google OAuth2 in C#? 【发布时间】:2020-10-18 03:11:33 【问题描述】:

我使用代码获取凭据

 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;
    

如何从这个凭证中获取电子邮件?我试过代码

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;
    

但看起来 People.Get("me") 不再可能了。我收到错误“Google.Apis.Requests.RequestError 旧版 People API 之前未在项目 618254727025 中使用或已禁用”

【问题讨论】:

【参考方案1】:

解决方案是获取访问令牌并尝试https://www.googleapis.com/oauth2/v2/userinfo?access_token=

【讨论】:

【参考方案2】:

在您的 范围 变量中。尝试只使用值“电子邮件”而不是 完整的 https 地址。 Web 链接中的范围关键字由空格分隔。这是我获取范围的一种方法:profile email openid。

为了测试这种方法,您可以在获取访问代码后手动将以下链接粘贴到浏览器中: https://www.googleapis.com/oauth2/v2/userinfo?access_token=[PASTE ACCESS CODE HERE]&[粘贴以下变量的值authorizationRequest HERE]

仅供参考:我正在修改可用的演示代码: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);

【讨论】:

【参考方案3】:

您可以使用users.getprofile,它将返回当前已通过身份验证的用户的电子邮件地址。

请求

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

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

回复


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

认识我

people.get的正确用法是“people/me”

 var request = plusService.People.Get("people/me")
 request.PersonFields("emailAddresses");
 var response = request.Execute();

【讨论】:

感谢您的回答...不幸的是,我不能在这里使用 GetProfile,只是因为我不想要求用户提供对他们 gmail 的访问权限。在我的情况下,这将是一个奇怪的解决方案......我只想检查我的应用程序中的用户是否可以访问某个谷歌帐户并获取他的电子邮件 但我知道可能我的所有架构都是错误的...... oauth 旨在不发送登录信息【参考方案4】:

我已经被这个问题困扰了好几天了。最后,感谢这个链接 (Check if user is already logged in),我了解到参数输入“用户”是关键问题。这个“用户”应该是windows登录用户(可以使用Enviroment.Username),而不是程序员或APP用户。 GoogleWebAuthorizationBroker.AuthorizeAsync 使用此用户名将其凭据保存在以下位置:

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

(类似这样)。 因此,如果您将“用户”提供给AuthorizeAsync,则凭证保存可能会出现问题,您的应用程序将严重挂起或滞后。而且,以后想用cred文件获取userinfo和email的时候,会出现问题(严重滞后)。在我的情况下,用户信息将全部丢失,只留下一个电子邮件地址。此外,您必须包括所需的两个范围:“https://www.googleapis.com/auth/userinfo.email”、“https://www.googleapis.com/auth/userinfo.profile”。希望这些有所帮助。

【讨论】:

更详细的获取邮件的代码是:Oauth2Service oauthService = new Oauth2Service(new BaseClientService.Initializer() HttpClientInitializer = credential, ApplicationName = "你的应用名称" ); var userinfo = oauthService.Userinfo.Get().ExecuteAsync().Result; var useremail = userinfo.Email;【参考方案5】:
    在范围内添加“https://www.googleapis.com/auth/userinfo.email”。 在回调中您将编码。使用从此代码获取令牌 json oauth2Client。 这个 json 包含 id_token 这基本上是一个 jwt 令牌,解析它你会得到email

【讨论】:

以上是关于在 C# 中使用 google OAuth2 后如何获取电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OAuth2 授权 Google 分析数据 API

Oauth2:远程服务器返回错误:(400) Bad Request

无法从 C# 中的 google api 令牌验证器获取数据

使用 suds 在 Python 中使用 OAuth2 进行 Google Adwords API 身份验证

Google文档是否已过时?

是否可以使用用户和凭据(JWT)登录,而 Oauth2 可以使用 google 登录?