c# - 使用带有 Gmail OAuth 的 MailKit 发送邮件

标签 c# email asp.net-core oauth-2.0 google-oauth

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

我已经在 Google API 控制台中设置了我的应用程序并创建了凭据。我找到了 this question在 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);
}

调用 Authenticate 出现以下错误:

MailKit.Security.AuthenticationException : AuthenticationInvalidCredentials: 5.7.8 Username and Password not accepted. Learn more at 5.7.8 https://support.google.com/mail/?p=BadCredentials m3-v6sm3447324wrs.39 - gsmtp

异常中的 Google 支持页面基本上只是说要么使用两步验证 + 应用密码,要么启用安全性较低的应用。这两个我都不要为什么在 .NET 中执行此操作如此困难?我以前用节点做过这个,它非常简单:

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
    }
});

请注意,我已经看到了this answer但我真的不明白我是如何获得谷歌信任的 X509 证书的。据我所知,在 Google 的文档中没有与此相关的内容。

最佳答案

解决方案是使用 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);
}

关于c# - 使用带有 Gmail OAuth 的 MailKit 发送邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51081442/

相关文章:

c# - 是否在 foreach 中使用 LINQ 语句重新评估每次迭代的语句

c# - 我怎样才能确保在页面继续之前加载一些js文件

php - 如何从 FB 库获取电子邮件 ID

php - 带有 curl 命令的 cron 守护进程正在发送空电子邮件

python - 用python解析outlook .msg文件

asp.net-core - asp.net Core Identity 中的 Multiple & SubDomain cookie

asp.net - ASP.NET Core 中的性能计数器在哪里?

c# - 查找具有用户指定大小的数组的平均值 C#

authentication - NET Core 反向代理和身份验证中间件

C# 如何解决使用 DirectoryInfo 时的限制?