C# - MailKit: SMTP, POP3, IMAP 지원 라이브러리
이번엔 라이브러리 소개를 해볼까요? ^^
Sending Emails with Gmail Using MailKit in .NET Web API: The Complete Guide
; https://dev.to/mamun_akand/sending-emails-with-gmail-using-mailkit-in-net-web-api-4lj5
jstedfast/MailKit - cross-platform mail client library built on top of MimeKit.
; https://github.com/jstedfast/MailKit
물론, 간단하게 SMTP를 이용해도 되지만,
C# - SmtpClient로 SMTP + SSL/TLS 서버를 이용하는 방법
; https://www.sysnet.pe.kr/2/0/11537
좀 더 기능이 다양한 MailKit도 좋은 선택이 될 수 있습니다. ^^ 사용법도 매우 간단한데요, 아래는 Gmail을 이용한 메일 발송 예제입니다.
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
// Install-Package MailKit
internal class Program
{
static async Task Main(string[] args)
{
var smtpServer = "smtp.gmail.com";
var port = 587;
// 사용자의 상황에 맞게 변경
(string fromMail, string password) = ("...user_email...", "...user password...");
string toEmail = "test@email.com";
string mailSubject = "Test Mail";
string mailBody = "This is a test mail";
var email = new MimeMessage();
email.From.Add(new MailboxAddress("Your Name", fromMail));
email.To.Add(new MailboxAddress("To Name", toEmail));
email.Subject = mailSubject;
email.Body = new TextPart("html") { Text = mailBody };
using var smtp = new SmtpClient();
await smtp.ConnectAsync(smtpServer, port, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync(fromMail, password);
await smtp.SendAsync(email);
await smtp.DisconnectAsync(true);
}
}
그 외,
POP3를 사용해 메일을 가져오는 예제나,
IMAP을 이용한 예제도 github에 잘 소개돼 있으니 참고하세요. ^^
만약 이런 오류가 발생한다면?
MailKit.Security.AuthenticationException
HResult=0x80131500
Message=535: 5.7.8 Username and Password not accepted. For more information, go to
5.7.8 https://support.google.com/mail/?p=BadCredentials d2e1a72fcca58-739710db4cfsm6759700b3a.176 - gsmtp
Source=MailKit
StackTrace:
at MailKit.Net.Smtp.SmtpClient.<AuthenticateAsync>d__7.MoveNext()
at ConsoleApp1.Program.<Main>d__0.MoveNext() in C:\temp\ConsoleApp1\ConsoleApp1\Program.cs:line 34
at ConsoleApp1.Program.<Main>(String[] args)
Inner Exception 1:
SmtpCommandException: 5.7.8 Username and Password not accepted. For more information, go to
5.7.8 https://support.google.com/mail/?p=BadCredentials d2e1a72fcca58-739710db4cfsm6759700b3a.176 - gsmtp
메시지에 나오듯이 코드에 입력한 "Username / Password"가 올바르지 않은 경우인데요, App password를 정상적으로 입력했는지 확인해 보세요.
Sign in with app passwords
; https://support.google.com/mail/answer/185833?hl=en
App passwords
; https://myaccount.google.com/apppasswords
.NET Framework 4 프로젝트에서 MailKit을 사용하는 경우 Connect 호출 시 이런 오류가 발생한다면?
smtp.Connect(smtpServer, port, SecureSocketOptions.StartTls);
[ArgumentException: The specified value is not valid in the 'SslProtocolType' enumeration.
Parameter name: sslProtocolType]
System.Net.Security.SslState.ValidateCreateContext(Boolean isServer, String targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus, Boolean checkCertName) +942
System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) +71
MailKit.Net.Smtp.SmtpClient.SslHandshake(SslStream ssl, String host, CancellationToken cancellationToken) in D:\src\MailKit\MailKit\Net\Smtp\SmtpClient.cs:1313
MailKit.Net.Smtp.SmtpClient.PostConnect(Stream stream, String host, Int32 port, SecureSocketOptions options, Boolean starttls, CancellationToken cancellationToken) in D:\src\MailKit\MailKit\Net\Smtp\SmtpClient.cs:1359
[SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.
This usually means that the SSL certificate presented by the server is not trusted by the system for one or more of
the following reasons:
1. The server is using a self-signed certificate which cannot be verified.
2. The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
3. A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.
4. The certificate presented by the server is expired or invalid.
5. The set of SSL/TLS protocols supported by the client and server do not match.
See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#ssl-handshake-exception for possible solutions.
]
MailKit.Net.Smtp.SmtpClient.PostConnect(Stream stream, String host, Int32 port, SecureSocketOptions options, Boolean starttls, CancellationToken cancellationToken) in D:\src\MailKit\MailKit\Net\Smtp\SmtpClient.cs:1376
MailKit.Net.Smtp.SmtpClient.Connect(String host, Int32 port, SecureSocketOptions options, CancellationToken cancellationToken) in D:\src\MailKit\MailKit\Net\Smtp\SmtpClient.cs:1507
...[생략]...
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +154
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4077
]
검색해 보면 이런 답변이 있는데요,
SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection
; https://stackoverflow.com/questions/59026301/sslhandshakeexception-an-error-occurred-while-attempting-to-establish-an-ssl-or
제시된 4개의 해결책 중에 CheckCertificateRevocation과
ServerCertificateValidationCallback은 답이 되지 않았고 SmtpClient.SslProtocols에 옵션을 설정하는 것으로 해결되었습니다.
using var smtp = new MailKit.Net.Smtp.SmtpClient();
smtp.SslProtocols = SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
smtp.Connect(smtpServer, port, SecureSocketOptions.StartTls);
smtp.Authenticate(fromMail, password);
smtp.Send(email);
smtp.Disconnect(true);
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]