ASP.NET 核心 - 发送电子邮件:请通过您的网络浏览器登录,然后重试
ASP.NET CORE - Send email: Please log in via your web browser and then try again
我正尝试在生产环境中发送一封带有用户注册验证 link 的邮件。
为此,我在 appsettings.json
中附上了发送邮件的 gmail 帐户的凭据
APPSETTINGS.JSON:
我的控制器发送邮件的动作如下:
[HttpPost]
public async Task<JsonResult> Register(AddUserViewModel model)
{
if (ModelState.IsValid)
{
User user = await _userHelper.AddUserAsync(model, imageId);
if (user == null)
{
return Json("Email repeat");
}
string myToken = await _userHelper.GenerateEmailConfirmationTokenAsync(user);
string tokenLink = Url.Action("ConfirmEmail", "Account", new
{
userid = user.Id,
token = myToken
}, protocol: HttpContext.Request.Scheme);
Response response = _mailHelper.SendMail(model.Username, "App - Confirmación de cuenta", $"<h1>App - Confirmación de cuenta</h1>" +
$"Para habilitar el usuario, " +
$"por favor hacer clic en el siguiente enlace: </br></br><a href = \"{tokenLink}\">Confirmar Email</a>");
if (response.IsSuccess)
{
return Json("Email send");
}
string message = response.Message;
return Json(message);
}
return Json("Model invalid");
}
returns一个Response的sendEmail方法如下:
public Response SendMail(string to, string subject, string body)
{
try
{
string from = _configuration["Mail:From"];
string smtp = _configuration["Mail:Smtp"];
string port = _configuration["Mail:Port"];
string password = _configuration["Mail:Password"];
MimeMessage message = new MimeMessage();
message.From.Add(new MailboxAddress(from));
message.To.Add(new MailboxAddress(to));
message.Subject = subject;
BodyBuilder bodyBuilder = new BodyBuilder
{
HtmlBody = body
};
message.Body = bodyBuilder.ToMessageBody();
using (SmtpClient client = new SmtpClient())
{
client.CheckCertificateRevocation = false;
client.Connect(smtp, int.Parse(port), false);
client.Authenticate(from, password);
client.Send(message);
client.Disconnect(true);
}
return new Response { IsSuccess = true };
}
catch (Exception ex)
{
return new Response
{
IsSuccess = false,
Message = ex.Message,
Result = ex
};
}
}
错误信息如下:
"534: 5.7.14
\u003Chttps://accounts.google.com/signin/continue?sarp=1\u0026scc=1\u0026plt=AKgnsbt\n5.7.14
GCim6bqtaJeANyyQ0NvegYJS8qnYbDSCz3M0IMvB-rgIFdr1rLrIl1wbt4DkimTvNMLDl\n5.7.14
8dSGZxGuAWmDwX6gPD1T_lJ3U1e0G8EEAu6Lgt3p5gk1yJpr85Pm2mBN9nO4G33Y\u003E\n5.7.14
Please log in via your web browser and then try again.\n5.7.14 Learn
more at\n5.7.14 https://support.google.com/mail/answer/78754
t15sm12262168pjy.17 - gsmtp"
我发送正确吗?
我应该更改任何 gmail 设置吗?
在开发环境中发送没有问题,对我有什么帮助或建议吗?
不建议直接使用 Gmail、Outlook 和类似的提供商,因为它们执行的检查可能会像您在此处看到的那样破坏您的代码。
这可能会在没有事先通知的情况下发生。相信我,它会不时发生。
常见问题
Web-based OAuth 流程
大多数提供商(特别是 Gmail)现在根据最新的 OAuth/OpenID 规范执行 web-based 流程,以实现更安全的 authentication/authorization。
这是我的第一个猜测:Gmail 身份验证(基于浏览器)只是阻止您的登录尝试,因为它希望您使用浏览器而不是简单地提交您的凭据。
IAM 解决方案完成了很多后台工作来帮助保护用户,即所谓的风险评估。这可能需要及时将验证码和 MFA 挑战发送回用户,因此 API 不会真正起作用,这是他们关注浏览器而不是简单地获取正确凭据的另一个原因.
Bot 预防
电子邮件提供商(特别是 Gmail)非常擅长检测可能的机器人程序,这是我的第二个猜测:它检测到您的服务是机器人程序并暂时冻结您的帐户以“保护您”。
这可能适用于较低的环境(又名:您的机器 and/or 测试环境)而不适用于生产环境,因为服务器 bot 预防系统通常会从浏览器检查 IP 地址、用户代理(如果any), API 调用率,鉴权率等。
使用率限制
在进行此类集成时,另一个可能会阻碍您的因素是速率限制。通常,500 messages/month.
可能的解决方案
解决方法 - 仍在使用 Gmail
要解决此问题并继续使用 Gmail,方法如下:
https://support.google.com/accounts/answer/185833?hl=en
它被称为 application password
并且是您在您的帐户上为允许登录的特定应用程序生成的不同密码。这将跳过 OAuth 和机器人验证(至少在大多数情况下)。
正确的long-term解决方案
修复此问题的唯一可靠方法是使用正确的电子邮件发送服务。诸如 Amazon Simple Email Service
、Sendgrid
或其他一些东西。
那是因为它们是为 API 调用而创建的,不会妨碍您。您可以在那里 set-up 您自己的域,包括 SPF
和 DKIM
密钥,这样您的收件人的电子邮件服务器就会将邮件识别为安全的,并且确实是来自您的(而不是随机垃圾邮件)。
我正尝试在生产环境中发送一封带有用户注册验证 link 的邮件。
为此,我在 appsettings.json
中附上了发送邮件的 gmail 帐户的凭据APPSETTINGS.JSON:
我的控制器发送邮件的动作如下:
[HttpPost]
public async Task<JsonResult> Register(AddUserViewModel model)
{
if (ModelState.IsValid)
{
User user = await _userHelper.AddUserAsync(model, imageId);
if (user == null)
{
return Json("Email repeat");
}
string myToken = await _userHelper.GenerateEmailConfirmationTokenAsync(user);
string tokenLink = Url.Action("ConfirmEmail", "Account", new
{
userid = user.Id,
token = myToken
}, protocol: HttpContext.Request.Scheme);
Response response = _mailHelper.SendMail(model.Username, "App - Confirmación de cuenta", $"<h1>App - Confirmación de cuenta</h1>" +
$"Para habilitar el usuario, " +
$"por favor hacer clic en el siguiente enlace: </br></br><a href = \"{tokenLink}\">Confirmar Email</a>");
if (response.IsSuccess)
{
return Json("Email send");
}
string message = response.Message;
return Json(message);
}
return Json("Model invalid");
}
returns一个Response的sendEmail方法如下:
public Response SendMail(string to, string subject, string body)
{
try
{
string from = _configuration["Mail:From"];
string smtp = _configuration["Mail:Smtp"];
string port = _configuration["Mail:Port"];
string password = _configuration["Mail:Password"];
MimeMessage message = new MimeMessage();
message.From.Add(new MailboxAddress(from));
message.To.Add(new MailboxAddress(to));
message.Subject = subject;
BodyBuilder bodyBuilder = new BodyBuilder
{
HtmlBody = body
};
message.Body = bodyBuilder.ToMessageBody();
using (SmtpClient client = new SmtpClient())
{
client.CheckCertificateRevocation = false;
client.Connect(smtp, int.Parse(port), false);
client.Authenticate(from, password);
client.Send(message);
client.Disconnect(true);
}
return new Response { IsSuccess = true };
}
catch (Exception ex)
{
return new Response
{
IsSuccess = false,
Message = ex.Message,
Result = ex
};
}
}
错误信息如下:
"534: 5.7.14 \u003Chttps://accounts.google.com/signin/continue?sarp=1\u0026scc=1\u0026plt=AKgnsbt\n5.7.14 GCim6bqtaJeANyyQ0NvegYJS8qnYbDSCz3M0IMvB-rgIFdr1rLrIl1wbt4DkimTvNMLDl\n5.7.14 8dSGZxGuAWmDwX6gPD1T_lJ3U1e0G8EEAu6Lgt3p5gk1yJpr85Pm2mBN9nO4G33Y\u003E\n5.7.14 Please log in via your web browser and then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/answer/78754 t15sm12262168pjy.17 - gsmtp"
我发送正确吗? 我应该更改任何 gmail 设置吗?
在开发环境中发送没有问题,对我有什么帮助或建议吗?
不建议直接使用 Gmail、Outlook 和类似的提供商,因为它们执行的检查可能会像您在此处看到的那样破坏您的代码。
这可能会在没有事先通知的情况下发生。相信我,它会不时发生。
常见问题
Web-based OAuth 流程
大多数提供商(特别是 Gmail)现在根据最新的 OAuth/OpenID 规范执行 web-based 流程,以实现更安全的 authentication/authorization。
这是我的第一个猜测:Gmail 身份验证(基于浏览器)只是阻止您的登录尝试,因为它希望您使用浏览器而不是简单地提交您的凭据。
IAM 解决方案完成了很多后台工作来帮助保护用户,即所谓的风险评估。这可能需要及时将验证码和 MFA 挑战发送回用户,因此 API 不会真正起作用,这是他们关注浏览器而不是简单地获取正确凭据的另一个原因.
Bot 预防
电子邮件提供商(特别是 Gmail)非常擅长检测可能的机器人程序,这是我的第二个猜测:它检测到您的服务是机器人程序并暂时冻结您的帐户以“保护您”。
这可能适用于较低的环境(又名:您的机器 and/or 测试环境)而不适用于生产环境,因为服务器 bot 预防系统通常会从浏览器检查 IP 地址、用户代理(如果any), API 调用率,鉴权率等。
使用率限制
在进行此类集成时,另一个可能会阻碍您的因素是速率限制。通常,500 messages/month.
可能的解决方案
解决方法 - 仍在使用 Gmail
要解决此问题并继续使用 Gmail,方法如下: https://support.google.com/accounts/answer/185833?hl=en
它被称为 application password
并且是您在您的帐户上为允许登录的特定应用程序生成的不同密码。这将跳过 OAuth 和机器人验证(至少在大多数情况下)。
正确的long-term解决方案
修复此问题的唯一可靠方法是使用正确的电子邮件发送服务。诸如 Amazon Simple Email Service
、Sendgrid
或其他一些东西。
那是因为它们是为 API 调用而创建的,不会妨碍您。您可以在那里 set-up 您自己的域,包括 SPF
和 DKIM
密钥,这样您的收件人的电子邮件服务器就会将邮件识别为安全的,并且确实是来自您的(而不是随机垃圾邮件)。