首页 > 解决方案 > 在无浏览器环境中获取 gmail 访问令牌并发送电子邮件

问题描述

我想学习如何使用 Mailkit 发送电子邮件。问题是我现在在我的 gmail 帐户中使用 2 因素身份验证,所以我不能使用简化的邮件发送选项。根据 Mailkit 文档 - 需要使用 Oath。

所以我在 Google API 中注册了一个新应用程序并获得了密钥。然后我尝试像这样进行身份验证:

var secrets = new ClientSecrets
{
    ClientId = "xxxx",
    ClientSecret = "yyyy"
};

var scopes = new string[] { GmailService.Scope.MailGoogleCom };

var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scopes, email, CancellationToken.None);
if (googleCredentials.Token.IsExpired(SystemClock.Default))
{
    await googleCredentials.RefreshTokenAsync(CancellationToken.None);
}

到达AuthorizeAsync线路后 - 打开一个新的浏览器窗口,我必须在其中输入我的凭据。如果我要在 Windows 上运行此应用程序,这将不是问题。但是,这是一个大问题。

我正在构建一个控制台 dotnet 核心应用程序,该应用程序旨在以 CLI 模式在 Linux 环境中运行。每次令牌过期时我都不能要求输入凭据..因为根本没有 GUI...

有没有一种方法可以让电子邮件发送“只是”工作而无需在外部应用程序中额外登录?

我刚刚想到,也许用简化的登录选项注册一个新的电子邮件帐户并在我的应用程序中使用它会更容易,而不是试图让当前的 Gmail 帐户工作。那么,有什么想法或建议吗?

标签: .net.net-coregmail-apimailkit

解决方案


您可以使用具有域范围委派 [3] 的服务帐户 [1] [2],这将授予您模拟域中任何 gmail 帐户的访问权限。选择项目后,您可以在 Cloud Platform 上创建服务帐号。

获得服务帐户后,您可以创建一个 p12 文件,您可以使用该文件获取在 Mailkit 上发送电子邮件所需的令牌。这是 Mailkit 文档中解释的代码,用于实现服务帐户 [4] 的使用:

var certificate = new X509Certificate2 (@"C:\path\to\certificate.p12", "password", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential (new ServiceAccountCredential
    .Initializer ("your-developer-id@developer.gserviceaccount.com") {
    // Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
    Scopes = new[] { "https://mail.google.com/" },
    User = "user@gmail.com"
}.FromCertificate (certificate));

bool result = await credential.RequestAccessTokenAsync (CancellationToken.None);

// Note: result will be true if the access token was received successfully

using (var client = new ImapClient ()) {
    client.Connect ("imap.gmail.com", 993, true);

    var oauth2 = new SaslMechanismOAuth2 ("user@gmail.com", credential.Token.AccessToken);
    client.Authenticate (oauth2);
}

代码第一个函数的路径字符串是您的服务帐户中p12文件的文件路径,您可以从云平台下载该文件。

编辑:

如果您不是 G Suite 管理员,一种解决方法是按照快速入门 [5] 中的方式实施授权流程,这只会在您第一次运行时在浏览器上提示您同意屏幕,并且它会创建一个令牌,您可以通过将令牌文件留在工作目录中来在代码的后续运行中使用它。您必须检查如何使用 MailKit 库中的 gmail 服务或凭据对象。

[1] https://cloud.google.com/iam/docs/service-accounts

[2] https://cloud.google.com/iam/docs/understanding-service-accounts

[3] https://developers.google.com/admin-sdk/directory/v1/guides/delegation

[4] https://github.com/jstedfast/MailKit/blob/master/FAQ.md#q-how-can-i-log-in-to-a-gmail-account-using-oauth-20

[5] https://developers.google.com/gmail/api/quickstart/dotnet


推荐阅读