使用 MailKit 和 Gmail OAuth 发送邮件

And*_*iss 8 c# email oauth-2.0 google-oauth asp.net-core

我正在尝试创建一个应用程序,该应用程序将在客户进行购买时向他们发送电子邮件。我们有自己的 GMail 帐户,我将用它来发送电子邮件。

我已经在 Google API 控制台中设置了我的应用程序并创建了凭据。我在 MailKit 的 GitHub 上发现了这个问题,它看起来很简单,但似乎对我不起作用。

这是我的代码:

var secrets = new ClientSecrets
{
    ClientId = [CLIENTID]
    ClientSecret = [SECRET]
};

var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, new[] { GmailService.Scope.MailGoogleCom }, email, CancellationToken.None);
await googleCredentials.RefreshTokenAsync(CancellationToken.None);

using (var client = new SmtpClient())
{
    client.Connect("smtp.gmail.com", 587);

    var credentials = new NetworkCredential(googleCredentials.UserId, googleCredentials.Token.AccessToken);
    client.Authenticate(credentials);

    await client.SendAsync(message);
    client.Disconnect(true);
}
Run Code Online (Sandbox Code Playgroud)

调用Authenticate给出了以下错误:

MailKit.Security.AuthenticationException : AuthenticationInvalidCredentials: 5.7.8 用户名和密码不被接受。在 5.7.8 https://support.google.com/mail/?p=BadCredentials m3-v6sm3447324wrs.39 - gsmtp 中了解更多 信息

例外中的 Google 支持页面基本上只是说要么使用两步验证 + 应用密码,要么启用不太安全的应用。这两个我都不想要。为什么在 .NET 中很难做到这一点?我之前用 node 做过这个,它非常简单:

var smtp = mailer.createTransport({
    service: "Gmail",
    auth: {
        type: "OAuth2",
        user: process.env.EMAIL,
        clientId: process.env.CLIENT_ID,
        clientSecret: process.env.CLIENT_SECRET,
        refreshToken: process.env.REFRESH_TOKEN
    }
});
Run Code Online (Sandbox Code Playgroud)

请不要说我已经看过这个答案,但我真的不明白我是如何获得 Google 信任的 X509 证书的。据我所知,谷歌的文档中没有与此相关的内容。

And*_*iss 12

解决方案是使用SaslMechanismOAuth2而不是NetworkCredential. 我现在有以下工作:

var secrets = new ClientSecrets
{
    ClientId = Environment.GetEnvironmentVariable("GMailClientId"),
    ClientSecret = Environment.GetEnvironmentVariable("GMailClientSecret")
};

var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, new[] { GmailService.Scope.MailGoogleCom }, email, CancellationToken.None);
if (googleCredentials.Token.IsExpired(SystemClock.Default))
{
    await googleCredentials.RefreshTokenAsync(CancellationToken.None);
}

using (var client = new SmtpClient())
{
    client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);

    var oauth2 = new SaslMechanismOAuth2(googleCredentials.UserId, googleCredentials.Token.AccessToken);
    client.Authenticate(oauth2);

    await client.SendAsync(message);
    client.Disconnect(true);
}
Run Code Online (Sandbox Code Playgroud)

  • 寻找服务帐户流程。 (4认同)

hub*_*t17 5

通过刷新令牌在 Gmail Mailkit 中发送电子邮件

    // https://console.developers.google.com
var secrets = new ClientSecrets
{
    ClientId = "",
    ClientSecret = ""
};
// Generating a refresh token - https://www.youtube.com/watch?v=hfWe1gPCnzc
var token = new TokenResponse { RefreshToken = "YourRefreshToken" };
var googleCredentials = new UserCredential(new GoogleAuthorizationCodeFlow(
    new GoogleAuthorizationCodeFlow.Initializer
    {
        ClientSecrets = secrets
    }), username, token);

emailClient.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);   
await googleCredentials.GetAccessTokenForRequestAsync();
var oauth2 = new SaslMechanismOAuth2(googleCredentials.UserId, googleCredentials.Token.AccessToken);
emailClient.Authenticate(oauth2);

await emailClient.SendAsync(message); // MimeMessage
emailClient.Disconnect(true);
Run Code Online (Sandbox Code Playgroud)