Отправка почты с помощью MailKit с Gmail OAuth - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь создать приложение, которое будет отправлять электронные письма клиентам, когда они совершают покупку. У нас есть собственная учетная запись GMail, которую я буду использовать для отправки электронных писем.

Я настроил свое приложение и создал учетные данные в консоли API Google. Я нашел этот вопрос на GitHub MailKit, который выглядел так, как будто это достаточно простой подход, но, похоже, он не работает для меня.

Вот мой код:

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 Имя пользователя и пароль не принято. Узнайте больше на 5,7,8 https://support.google.com/mail/?p=BadCredentials м3-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
    }
});

Обратите внимание, что я уже видел этот ответ , но я не совсем понимаю, как мне получить сертификат X509, которому доверяет Google. Насколько я вижу, в документации Google нет ничего, связанного с этим.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Отправка электронной почты в 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);
0 голосов
/ 28 июня 2018

Решение состояло в том, чтобы аутентифицироваться с 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...