Sdílet prostřednictvím


Potvrzení účtu a obnovení hesla v ASP.NET Core Blazor

Tento článek vysvětluje, jak nakonfigurovat webovou aplikaci ASP.NET Core Blazor s potvrzením e-mailu a obnovením hesla.

Obor názvů

Obor názvů aplikace používaný v příkladu v tomto článku je BlazorSample. Aktualizujte příklady kódu tak, aby používaly obor názvů vaší aplikace.

Výběr a konfigurace poskytovatele e-mailu

V tomto článku se k odesílání e-mailů používá transakční rozhraní API mailchimpu prostřednictvím Mandrill.net . K odesílání e-mailů místo SMTP doporučujeme použít e-mailovou službu. Konfigurace a zabezpečení protokolu SMTP je obtížné. Bez ohledu na to, kterou e-mailovou službu používáte, získejte přístup k pokynům pro aplikace .NET, vytvořte účet, nakonfigurujte klíč rozhraní API pro svou službu a nainstalujte všechny požadované balíčky NuGet.

Vytvořte třídu pro načtení klíče zabezpečeného e-mailového rozhraní API. Příklad v tomto článku používá třídu pojmenovanou AuthMessageSenderOptionsEmailAuthKey s vlastností k uložení klíče.

AuthMessageSenderOptions:

namespace BlazorSample;

public class AuthMessageSenderOptions
{
    public string? EmailAuthKey { get; set; }
}

AuthMessageSenderOptions Zaregistrujte instanci konfigurace v Program souboru:

builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);

Konfigurace tajného klíče uživatele pro klíč zabezpečení poskytovatele

Klíč nastavte pomocí nástroje secret-manager. V následujícím příkladu je EmailAuthKey název klíče a klíč je reprezentován zástupným {KEY} symbolem. V příkazovém prostředí přejděte do kořenové složky aplikace a spusťte následující příkaz s klíčem rozhraní API:

dotnet user-secrets set "EmailAuthKey" "{KEY}"

Další informace najdete v tématu Sejf ukládání tajných kódů aplikací při vývoji v ASP.NET Core.

Implementovat IEmailSender

Implementujte IEmailSender pro zprostředkovatele. Následující příklad je založený na transakčním rozhraní API mailchimpu pomocí Mandrill.net. Informace o tom, jak implementovat odesílání zpráv v metodě, najdete v Execute dokumentaci jiného poskytovatele.

Components/Account/EmailSender.cs:

using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Mandrill;
using Mandrill.Model;
using BlazorSample.Data;

namespace BlazorSample.Components.Account;

public class EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
    ILogger<EmailSender> logger) : IEmailSender<ApplicationUser>
{
    private readonly ILogger logger = logger;

    public AuthMessageSenderOptions Options { get; } = optionsAccessor.Value;

    public Task SendConfirmationLinkAsync(ApplicationUser user, string email, 
        string confirmationLink) => SendEmailAsync(email, "Confirm your email", 
        $"Please confirm your account by " +
        "<a href='{confirmationLink}'>clicking here</a>.");

    public Task SendPasswordResetLinkAsync(ApplicationUser user, string email, 
        string resetLink) => SendEmailAsync(email, "Reset your password", 
        $"Please reset your password by <a href='{resetLink}'>clicking here</a>.");

    public Task SendPasswordResetCodeAsync(ApplicationUser user, string email, 
        string resetCode) => SendEmailAsync(email, "Reset your password", 
        $"Please reset your password using the following code: {resetCode}");

    public async Task SendEmailAsync(string toEmail, string subject, string message)
    {
        if (string.IsNullOrEmpty(Options.EmailAuthKey))
        {
            throw new Exception("Null EmailAuthKey");
        }

        await Execute(Options.EmailAuthKey, subject, message, toEmail);
    }

    public async Task Execute(string apiKey, string subject, string message, 
        string toEmail)
    {
        var api = new MandrillApi(apiKey);
        var mandrillMessage = new MandrillMessage("sarah@contoso.com", toEmail, 
            subject, message);
        await api.Messages.SendAsync(mandrillMessage);

        logger.LogInformation("Email to {EmailAddress} sent!", toEmail);
    }
}

Poznámka:

Základní obsah zpráv může vyžadovat speciální kódování pro poskytovatele e-mailové služby. Pokud odkazy v textu zprávy nelze sledovat, projděte si dokumentaci poskytovatele služeb.

Konfigurace aplikace pro podporu e-mailu

Program V souboru změňte implementaci odesílatele e-mailu na EmailSender:

- builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
+ builder.Services.AddSingleton<IEmailSender<ApplicationUser>, EmailSender>();

IdentityNoOpEmailSender Odeberte (Components/Account/IdentityNoOpEmailSender.cs) z aplikace.

V komponentě RegisterConfirmation (Components/Account/Pages/RegisterConfirmation.razor) odeberte podmíněný blok v @code bloku, který zkontroluje, zda EmailSender je IdentityNoOpEmailSender:

- else if (EmailSender is IdentityNoOpEmailSender)
- {
-     ...
- }

Také v komponentě RegisterConfirmation odeberte značky Razor a kód pro kontrolu emailConfirmationLink pole a ponechte jen řádek s pokynem uživateli, aby zkontroloval svůj e-mail ...

- @if (emailConfirmationLink is not null)
- {
-     ...
- }
- else
- {
     <p>Please check your email to confirm your account.</p>
- }

@code {
-    private string? emailConfirmationLink;

     ...
}

Vypršení časového limitu e-mailu a aktivity

Výchozí časový limit nečinnosti je 14 dnů. Následující kód nastaví časový limit nečinnosti na 5 dnů s posuvným vypršením platnosti:

builder.Services.ConfigureApplicationCookie(options => {
    options.ExpireTimeSpan = TimeSpan.FromDays(5);
    options.SlidingExpiration = true;
});

Změna životnosti všech tokenů ochrany dat

Následující kód změní časový limit všech tokenů ochrany dat na 3 hodiny:

builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
    options.TokenLifespan = TimeSpan.FromHours(3));

Předdefinované Identity tokeny uživatele (AspNetCore/src/Identity/Extensions.Core/src/TokenOptions.cs) mají časový limit jednoho dne.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Změna životnosti e-mailového tokenu

Výchozí životnost Identity tokenů uživatele je jeden den.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Pokud chcete změnit životnost e-mailového tokenu, přidejte vlastní a DataProtectorTokenProvider<TUser>DataProtectionTokenProviderOptions:

CustomTokenProvider.cs:

using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;

namespace BlazorSample;

public class CustomEmailConfirmationTokenProvider<TUser>
    : DataProtectorTokenProvider<TUser> where TUser : class
{
    public CustomEmailConfirmationTokenProvider(
        IDataProtectionProvider dataProtectionProvider,
        IOptions<EmailConfirmationTokenProviderOptions> options,
        ILogger<DataProtectorTokenProvider<TUser>> logger)
        : base(dataProtectionProvider, options, logger)
    {
    }
}

public class EmailConfirmationTokenProviderOptions 
    : DataProtectionTokenProviderOptions
{
    public EmailConfirmationTokenProviderOptions()
    {
        Name = "EmailDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromHours(4);
    }
}

public class CustomPasswordResetTokenProvider<TUser> 
    : DataProtectorTokenProvider<TUser> where TUser : class
{
    public CustomPasswordResetTokenProvider(
        IDataProtectionProvider dataProtectionProvider,
        IOptions<PasswordResetTokenProviderOptions> options,
        ILogger<DataProtectorTokenProvider<TUser>> logger)
        : base(dataProtectionProvider, options, logger)
    {
    }
}

public class PasswordResetTokenProviderOptions : 
    DataProtectionTokenProviderOptions
{
    public PasswordResetTokenProviderOptions()
    {
        Name = "PasswordResetDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromHours(3);
    }
}

Nakonfigurujte služby tak, aby používaly vlastního zprostředkovatele tokenu Program v souboru:

builder.Services.AddIdentityCore<ApplicationUser>(options =>
    {
        options.SignIn.RequireConfirmedAccount = true;
        options.Tokens.ProviderMap.Add("CustomEmailConfirmation",
            new TokenProviderDescriptor(
                typeof(CustomEmailConfirmationTokenProvider<ApplicationUser>)));
        options.Tokens.EmailConfirmationTokenProvider = 
            "CustomEmailConfirmation";
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

builder.Services
    .AddTransient<CustomEmailConfirmationTokenProvider<ApplicationUser>>();

Odstraňování potíží

Pokud vám nefunguje e-mail:

  • Nastavte zarážku EmailSender.Execute pro ověření SendEmailAsync .
  • Vytvořte konzolovou aplikaci pro odesílání e-mailů pomocí kódu podobného EmailSender.Execute ladění problému.
  • Zkontrolujte stránky historie e-mailů účtu na webu poskytovatele e-mailu.
  • Zkontrolujte, jestli ve složce spamu nezískáte zprávy.
  • Zkuste jiný e-mailový alias u jiného poskytovatele e-mailu, jako je Microsoft, Yahoo nebo Gmail.
  • Zkuste odeslat do různých e-mailových účtů.

Upozorňující

Nepoužívejte produkční tajné kódy při testování a vývoji. Pokud aplikaci publikujete do Azure, nastavte tajné kódy jako nastavení aplikace na portálu Azure Web App. Konfigurační systém je nastavený tak, aby načítal klíče z proměnných prostředí.

Povolení potvrzení účtu po tom, co má web uživatele

Povolení potvrzení účtu na webu s uživateli zamkne všechny stávající uživatele. Stávající uživatelé jsou uzamčení, protože jejich účty se nepotvrdí. Pokud chcete obejít stávající uzamčení uživatele, použijte jeden z následujících přístupů:

  • Aktualizujte databázi tak, aby označí všechny existující uživatele jako potvrzené.
  • Potvrďte existující uživatele. Například dávkové odesílání e-mailů s potvrzovanými odkazy.

Další materiály