Asp.Net Core Identity SendGrid 邮件未发送

Asp.Net Core Identity SendGrid mails are not being sent

我想找出为什么在创建新用户帐户时我的应用程序没有发送帐户验证电子邮件。

我第一次尝试就发送了两封电子邮件。这些电子邮件最终进入了我的垃圾邮件过滤器,但它们确实通过了。我不知道从那以后发生了什么变化。

检查 SendGrid 控制面板,我可以确认在我尝试的第一天发送了两封电子邮件,但我后来的 none 次尝试都生成了任何电子邮件。

This article建议在EmailSender.Execute上设置断点。我这样做了,发现确实没有被击中。我该如何进一步调试?

SendGrid账户信息在secrets.json中指定:

{
  "SendGridUser": "{account name}",
  "SendGridKey": "{api-key}"
}

在Startup.cs中配置了一个服务:

services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);

AuthMessageSenderOptions:

public class AuthMessageSenderOptions
{
    public string SendGridUser { get; set; }
    public string SendGridKey { get; set; }
}

EmailSender 服务:

public class EmailSender : IEmailSender
{
    public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
    {
        Options = optionsAccessor.Value;
    }

    public AuthMessageSenderOptions Options { get; } //set only via Secret Manager

    public Task SendEmailAsync(string email, string subject, string message)
    {
        return Execute(Options.SendGridKey, subject, message, email);
    }

    public Task Execute(string apiKey, string subject, string message, string email)
    {
        var client = new SendGridClient(apiKey);
        var msg = new SendGridMessage()
        {
            From = new EmailAddress("my@email.com", Options.SendGridUser),
            Subject = subject,
            PlainTextContent = message,
            HtmlContent = message
        };
        msg.AddTo(new EmailAddress(email));

        // Disable click tracking.
        // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
        msg.SetClickTracking(false, false);

        return client.SendEmailAsync(msg);
    }
}

用户是这样创建的:

// user is an ApplicationUser-object
IdentityResult result = await userManager.CreateAsync(auto.Map<ApplicationUser>(user), "P&55w0rd");
if (result.Succeeded)
{
    ApplicationUser u = await userManager.FindByNameAsync(user.UserName);
    if (u != null)
    { 
        // newUser.RN is the role name to be assigned to the new user
        await userManager.AddToRoleAsync(u, newUser.RN);
    }
    return RedirectToAction("Details", new { id = user.Id });
}
else
{
    foreach (var error in result.Errors)
    {
        ModelState.AddModelError("", error.Description);
    }
}

一个新用户被创建,添加到角色,我们被重定向到 Users/Details/{id},但帐户验证电子邮件没有发送。

如果 Identity 仅通过设置 EmailSender 默认执行此操作,我会感到惊讶。您似乎没有提供任何确认逻辑,也无处调用 EmailSender。

您需要在创建用户的控制器中将 IEmailSender 作为服务注入,并添加逻辑以生成确认令牌并实际发送电子邮件。

我期待的是:

var token = await userManager.GenerateEmailConfirmationTokenAsync(user);
var confirmationLink = Url.Action(nameof(ConfirmEmail), "Account", 
   new { token , email = user.Email }, 
   Request.Scheme);
await _emailSender.SendEmailAsync(user.Email, "Confirmation email link", confirmationLink);

当然你可以进一步看看如何让你的电子邮件更漂亮,但这是它的核心。

另外,为了确保你有全貌,Identity默认也没有提供email实现,你也得设置一下:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/accconfirm?view=aspnetcore-3.1&tabs=visual-studio#install-sendgrid

如果发件人的电子邮件未正确验证,Sendgrid 将不会发送电子邮件。 希望这对某人有帮助。 文档:https://app.sendgrid.com/settings/sender_auth