Aracılığıyla paylaş


ASP.NET Core'da hesap onayı ve parola kurtarma Blazor

Bu makalede, e-posta onayı ve parola kurtarma ile ASP.NET Core Blazor Web Uygulamasını yapılandırma işlemi açıklanır.

Ad Alanı

Bu makaledeki örnek tarafından kullanılan uygulamanın ad alanıdır BlazorSample. Uygulamanızın ad alanını kullanmak için kod örneklerini güncelleştirin.

E-posta sağlayıcısı seçme ve yapılandırma

Bu makalede Mailchimp'in İşlem API'si e-posta göndermek için Mandrill.net aracılığıyla kullanılır. SMTP yerine e-posta göndermek için bir e-posta hizmeti kullanmanızı öneririz. SMTP'nin düzgün yapılandırılması ve güvenliğinin zor olması. Hangi e-posta hizmetini kullanırsanız kullanın, .NET uygulamaları için yönergelerine erişin, bir hesap oluşturun, hizmetleri için bir API anahtarı yapılandırın ve gerekli tüm NuGet paketlerini yükleyin.

Güvenli e-posta API anahtarını getirmek için bir sınıf oluşturun. Bu makaledeki örnekte anahtarı tutmak için özelliği ile adlı AuthMessageSenderOptions bir EmailAuthKey sınıf kullanılır.

AuthMessageSenderOptions:

namespace BlazorSample;

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

Yapılandırma örneğini AuthMessageSenderOptions dosyaya Program kaydedin:

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

Sağlayıcının güvenlik anahtarı için kullanıcı gizli dizisi yapılandırma

Gizli dizi yöneticisi aracıyla anahtarı ayarlayın. Aşağıdaki örnekte anahtar adıdır EmailAuthKey ve anahtar yer tutucu tarafından {KEY} temsil edilir. Komut kabuğunda uygulamanın kök klasörüne gidin ve API anahtarıyla aşağıdaki komutu yürütür:

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

Daha fazla bilgi için bkz. ASP.NET Core'da geliştirme aşamasında Kasa uygulama gizli dizilerinin depolanması.

Uygulamak IEmailSender

Sağlayıcı için uygulayın IEmailSender . Aşağıdaki örnek, mailchimp'in Mandrill.net kullanan İşlem API'sini temel alır. Farklı bir sağlayıcı için yönteminde ileti göndermeyi uygulama hakkındaki belgelerine Execute bakın.

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);
    }
}

Not

İletilerin gövde içeriği, e-posta hizmeti sağlayıcısı için özel kodlama gerektirebilir. İleti gövdesindeki bağlantılar izlenemiyorsa hizmet sağlayıcısının belgelerine bakın.

Uygulamayı e-postayı destekleyecek şekilde yapılandırma

Program dosyasında, e-posta gönderen uygulamasını olarak EmailSenderdeğiştirin:

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

IdentityNoOpEmailSender (Components/Account/IdentityNoOpEmailSender.cs) öğesini uygulamadan kaldırın.

() bileşenindeComponents/Account/Pages/RegisterConfirmation.razor, öğesinin RegisterConfirmation olup IdentityNoOpEmailSenderolmadığını EmailSender denetleen bloktaki @code koşullu bloğu kaldırın:

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

Ayrıca bileşendeRegisterConfirmation, alanı denetlemek emailConfirmationLink için işaretlemeyi ve kodu kaldırın Razor ve kullanıcıya e-postasını denetleme talimatı veren satırı bırakın...

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

@code {
-    private string? emailConfirmationLink;

     ...
}

E-posta ve etkinlik zaman aşımı

Varsayılan etkinlik dışı zaman aşımı 14 gündür. Aşağıdaki kod, etkinlik dışı zaman aşımını kayan süre sonuyla 5 güne ayarlar:

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

Tüm veri koruma belirteci kullanım ömrünü değiştirme

Aşağıdaki kod tüm veri koruma belirteçleri zaman aşımı süresini 3 saat olarak değiştirir:

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

Yerleşik Identity kullanıcı belirteçleri (AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs) bir günlük zaman aşımına sahiptir.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

E-posta belirteci kullanım ömrünü değiştirme

Kullanıcı belirteçlerinin Identity varsayılan belirteç ömrü bir gündür.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

E-posta belirteci kullanım ömrünü değiştirmek için özel DataProtectorTokenProvider<TUser> ve DataProtectionTokenProviderOptionsekleyin:

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);
    }
}

Hizmetleri dosyadaki özel belirteç sağlayıcısını Program kullanacak şekilde yapılandırın:

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>>();

Sorun giderme

E-postayı çalıştıramıyorsanız:

  • çağrıldığını doğrulamak SendEmailAsync için içinde EmailSender.Execute bir kesme noktası ayarlayın.
  • Sorunun hatalarını ayıklamaya benzer bir kod kullanarak e-posta göndermek için EmailSender.Execute bir konsol uygulaması oluşturun.
  • E-posta sağlayıcısının web sitesindeki hesap e-posta geçmişi sayfalarını gözden geçirin.
  • İstenmeyen posta klasörünüzde iletiler olup olmadığını denetleyin.
  • Microsoft, Yahoo veya Gmail gibi farklı bir e-posta sağlayıcısında başka bir e-posta diğer adı deneyin.
  • Farklı e-posta hesaplarına göndermeyi deneyin.

Uyarı

Test ve geliştirme aşamasında üretim gizli dizilerini kullanmayın. Uygulamayı Azure'da yayımlarsanız, Azure Web App portalında gizli dizileri uygulama ayarları olarak ayarlayın. Yapılandırma sistemi, ortam değişkenlerinden anahtarları okuyacak şekilde ayarlanır.

Bir sitede kullanıcılar olduktan sonra hesap onaylarını etkinleştirme

Kullanıcıların olduğu bir sitede hesap onayını etkinleştirmek, mevcut tüm kullanıcıları kilitler. Hesapları onaylanmamış olduğundan mevcut kullanıcılar kilitlenir. Mevcut kullanıcı kilitlenmesine geçici bir çözüm bulmak için aşağıdaki yaklaşımlardan birini kullanın:

  • Tüm mevcut kullanıcıları onaylandı olarak işaretlemek için veritabanını güncelleştirin.
  • Mevcut kullanıcıları onaylayın. Örneğin, onay bağlantıları içeren toplu gönderme e-postaları.

Ek kaynaklar