Подтверждение учетной записи и восстановление пароля в ASP.NET Core
Рик Андерсон, Понант и Джо Audette
В этом руководстве показано, как создать приложение ASP.NET Core с подтверждением электронной почты и сбросом пароля. Это руководство не является начальным разделом. Предполагается, что вы знакомы со следующими темами.
Инструкции Blazor , которые добавляются в инструкции, приведенные в этой статье, см . в разделе "Подтверждение учетной записи" и восстановление паролей в ASP.NET Core Blazor.
Необходимые компоненты
- Пакет SDK для .NET Core 6.0 или более поздней версии
- Успешно отправить сообщение электронной почты из консольного приложения C#.
Создание и тестирование веб-приложения с проверкой подлинности
Выполните следующие команды, чтобы создать веб-приложение с проверкой подлинности.
dotnet new webapp -au Individual -o WebPWrecover
cd WebPWrecover
dotnet run
Регистрация пользователя с имитацией подтверждения электронной почты
Запустите приложение, выберите ссылку "Регистрация " и зарегистрируйте пользователя. После регистрации вы будете перенаправлены на /Identity/Account/RegisterConfirmation
страницу, содержащую ссылку для имитации подтверждения электронной почты:
- Выберите ссылку
Click here to confirm your account
. - Выберите ссылку для входа и войдите с теми же учетными данными.
- Выберите ссылку
Hello YourEmail@provider.com!
, которая перенаправляется на страницу/Identity/Account/Manage/PersonalData
. - Перейдите на вкладку "Персональные данные " слева и нажмите кнопку "Удалить".
Ссылка Click here to confirm your account
отображается, так как IEmailSender не реализована и зарегистрирована в контейнере внедрения зависимостей. См. RegisterConfirmation
источник.
Примечание.
По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Настройка поставщика электронной почты
В этом руководстве SendGrid используется для отправки электронной почты. Для отправки электронной почты требуется учетная запись SendGrid и ключ. Мы рекомендуем использовать SendGrid или другую службу электронной почты для отправки электронной почты, а не SMTP. SMTP трудно защитить и настроить правильно.
Для учетной записи SendGrid может потребоваться добавить отправителя.
Создайте класс для получения безопасного ключа электронной почты. Для этого примера создайте Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
Настройка секретов пользователя SendGrid
SendGridKey
Установите средство secret-manager. Например:
dotnet user-secrets set SendGridKey <key>
Successfully saved SendGridKey to the secret store.
В Windows диспетчер секретов хранит пары "ключи-значение" в файле в secrets.json
каталоге %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
.
Содержимое secrets.json
файла не шифруется. В следующей разметке secrets.json
показан файл. Значение SendGridKey
было удалено.
{
"SendGridKey": "<key removed>"
}
Дополнительные сведения см. в шаблоне параметров и конфигурации.
Установка SendGrid
В этом руководстве показано, как добавить Уведомления по электронной почте через SendGrid, но другие поставщики электронной почты можно использовать.
SendGrid
Установите пакет NuGet:
В консоли диспетчер пакетов введите следующую команду:
Install-Package SendGrid
См. статью "Начало работы с SendGrid для бесплатной регистрации для бесплатной учетной записи SendGrid".
Реализация IEmailSender
Чтобы реализовать IEmailSender
, создайте Services/EmailSender.cs
код, аналогичный следующему:
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
namespace WebPWrecover.Services;
public class EmailSender : IEmailSender
{
private readonly ILogger _logger;
public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
ILogger<EmailSender> logger)
{
Options = optionsAccessor.Value;
_logger = logger;
}
public AuthMessageSenderOptions Options { get; } //Set with Secret Manager.
public async Task SendEmailAsync(string toEmail, string subject, string message)
{
if (string.IsNullOrEmpty(Options.SendGridKey))
{
throw new Exception("Null SendGridKey");
}
await Execute(Options.SendGridKey, subject, message, toEmail);
}
public async Task Execute(string apiKey, string subject, string message, string toEmail)
{
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("Joe@contoso.com", "Password Recovery"),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(toEmail));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
var response = await client.SendEmailAsync(msg);
_logger.LogInformation(response.IsSuccessStatusCode
? $"Email to {toEmail} queued successfully!"
: $"Failure Email to {toEmail}");
}
}
Настройка приложения для поддержки электронной почты
Добавьте в файл Program.cs
следующий код:
- Добавьте
EmailSender
в качестве временной службы. AuthMessageSenderOptions
Зарегистрируйте экземпляр конфигурации.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Отключение проверки учетной записи по умолчанию при создании шаблонов account.RegisterConfirmation
Этот раздел применяется только при Account.RegisterConfirmation
создании шаблонов. Пропустите этот раздел, если вы не создали шаблон Account.RegisterConfirmation
.
Пользователь перенаправляется на Account.RegisterConfirmation
место, где можно выбрать ссылку, чтобы подтвердить учетную запись. Значение по умолчанию Account.RegisterConfirmation
используется только для тестирования, автоматическая проверка учетной записи должна быть отключена в рабочем приложении.
Чтобы требовать подтвержденную учетную запись и предотвратить немедленный вход при регистрации, задайте DisplayConfirmAccountLink = false
в шаблонном /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
файле:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
namespace WebPWrecover.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string Email { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public bool DisplayConfirmAccountLink { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
returnUrl = returnUrl ?? Url.Content("~/");
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
}
Этот шаг необходим только при Account.RegisterConfirmation
создании шаблонов. Нестандартная регистрация RegisterConfirmation автоматически обнаруживает, когда IEmailSender была реализована и зарегистрирована в контейнере внедрения зависимостей.
Регистрация, подтверждение электронной почты и сброс пароля
Запустите веб-приложение и проверьте поток подтверждения учетной записи и восстановления паролей.
- Запустите приложение и зарегистрируйте нового пользователя
- Проверьте электронную почту по ссылке подтверждения учетной записи. Если вы не получите сообщение электронной почты, просмотрите отладочную почту .
- Щелкните ссылку, чтобы подтвердить сообщение электронной почты.
- Войдите с помощью электронной почты и пароля.
- Выйти.
Тестирование сброса пароля
- Если вы вошли в систему, выберите "Выйти".
- Выберите ссылку "Войти" и щелкните ссылку "Забыл пароль"?
- Введите сообщение электронной почты, которое вы использовали для регистрации учетной записи.
- Отправляется сообщение электронной почты со ссылкой на сброс пароля. Проверьте электронную почту и щелкните ссылку, чтобы сбросить пароль. После успешного сброса пароля вы можете войти с помощью электронной почты и нового пароля.
Подтверждение повторной отправки электронной почты
Выберите ссылку подтверждения повторной отправки электронной почты на странице входа .
Изменение времени ожидания электронной почты и действий
Время ожидания бездействия по умолчанию — 14 дней. Следующий код задает время ожидания бездействия в течение 5 дней:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
builder.Services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
var app = builder.Build();
// Code removed for brevity
Изменение срока жизни маркера защиты данных
Следующий код изменяет период ожидания всех маркеров защиты данных на 3 часа:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
builder.Services.Configure<DataProtectionTokenProviderOptions>(o =>
o.TokenLifespan = TimeSpan.FromHours(3));
var app = builder.Build();
// Code removed for brevity.
Встроенные Identity маркеры пользователей (см . раздел AspNetCore/src/IdentityExtensions.Core/src/TokenOptions.cs )имеют однодневное время ожидания.
Изменение срока жизни маркера электронной почты
Срок действия маркера по умолчанию для маркеров Identity пользователя составляет один день. В этом разделе показано, как изменить срок жизни маркера электронной почты.
Добавление пользовательского DataProtectorTokenProvider<TUser> и DataProtectionTokenProviderOptions:
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);
}
}
Добавьте настраиваемого поставщика в контейнер службы:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
using WebPWrecover.TokenProviders;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.Tokens.ProviderMap.Add("CustomEmailConfirmation",
new TokenProviderDescriptor(
typeof(CustomEmailConfirmationTokenProvider<IdentityUser>)));
config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";
}).AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
var app = builder.Build();
// Code removed for brevity.
Отладка электронной почты
Если вы не можете получить электронную почту, выполните следующие действия:
- Задайте точку останова для
EmailSender.Execute
проверкиSendGridClient.SendEmailAsync
. - Создайте консольное приложение для отправки электронной почты с помощью аналогичного кода
EmailSender.Execute
. - Просмотрите страницу действия электронной почты.
- Проверьте папку нежелательной почты.
- Попробуйте другой псевдоним электронной почты в другом поставщике электронной почты (Microsoft, Yahoo, Gmail и т. д.)
- Попробуйте отправить в разные учетные записи электронной почты.
Рекомендуется не использовать рабочие секреты в тестировании и разработке. При публикации приложения в Azure задайте секреты SendGrid в качестве параметров приложения на портале веб-приложения Azure. Система конфигурации настроена для чтения ключей из переменных среды.
Объединение учетных записей для входа в социальных сетях и локальных учетных записей входа
Чтобы завершить этот раздел, необходимо сначала включить внешний поставщик проверки подлинности. Ознакомьтесь с проверкой подлинности Facebook, Google и внешним поставщиком.
Вы можете объединить локальные и социальные учетные записи, щелкнув ссылку электронной почты. В следующей последовательности "RickAndMSFT@gmail.com" сначала создается в качестве локального входа. Однако сначала можно создать учетную запись в качестве имени входа в социальных сетях, а затем добавить локальное имя входа.
Щелкните ссылку "Управление ". Обратите внимание на внешние (социальные имена входа), связанные с этой учетной записью.
Щелкните ссылку на другую службу входа и примите запросы приложения. На следующем изображении Facebook является внешним поставщиком проверки подлинности:
Две учетные записи были объединены. Вы можете войти с помощью любой учетной записи. Возможно, вы хотите, чтобы пользователи добавляли локальные учетные записи в случае, если служба проверки подлинности в социальных сетях отключена, или, скорее всего, они потеряли доступ к своей учетной записи социальных параметров.
Включение подтверждения учетной записи после того, как сайт имеет пользователей
Включение подтверждения учетной записи на сайте с пользователями блокирует всех существующих пользователей. Существующие пользователи заблокированы, так как их учетные записи не подтверждены. Чтобы обойти существующую блокировку пользователей, используйте один из следующих подходов:
- Обновите базу данных, чтобы пометить всех существующих пользователей как подтвержденных.
- Подтвердите существующих пользователей. Например, пакетная отправка сообщений электронной почты с ссылками подтверждения.
Необходимые компоненты
Пакет SDK для .NET Core 3.0 или более поздней версии
Создание и тестирование веб-приложения с проверкой подлинности
Выполните следующие команды, чтобы создать веб-приложение с проверкой подлинности.
dotnet new webapp -au Individual -uld -o WebPWrecover
cd WebPWrecover
dotnet run
Запустите приложение, выберите ссылку "Регистрация " и зарегистрируйте пользователя. После регистрации вы будете перенаправлены на /Identity/Account/RegisterConfirmation
страницу, содержащую ссылку для имитации подтверждения электронной почты:
- Выберите ссылку
Click here to confirm your account
. - Выберите ссылку для входа и войдите с теми же учетными данными.
- Выберите ссылку
Hello YourEmail@provider.com!
, которая перенаправляет вас на страницу/Identity/Account/Manage/PersonalData
. - Перейдите на вкладку "Персональные данные " слева и нажмите кнопку "Удалить".
Настройка поставщика электронной почты
В этом руководстве SendGrid используется для отправки электронной почты. Вы можете использовать другие поставщики электронной почты. Мы рекомендуем использовать SendGrid или другую службу электронной почты для отправки электронной почты. SMTP сложно настроить так, чтобы почта не помечена как спам.
Для учетной записи SendGrid может потребоваться добавить отправителя.
Создайте класс для получения безопасного ключа электронной почты. Для этого примера создайте Services/AuthMessageSenderOptions.cs
:
namespace WebPWrecover.Services;
public class AuthMessageSenderOptions
{
public string? SendGridKey { get; set; }
}
Настройка секретов пользователя SendGrid
SendGridKey
Установите средство secret-manager. Например:
dotnet user-secrets set SendGridKey <SG.key>
Successfully saved SendGridKey = SG.keyVal to the secret store.
В Windows диспетчер секретов хранит пары "ключи-значение" в файле в secrets.json
каталоге %APPDATA%/Microsoft/UserSecrets/<WebAppName-userSecretsId>
.
Содержимое secrets.json
файла не шифруется. В следующей разметке secrets.json
показан файл. Значение SendGridKey
было удалено.
{
"SendGridKey": "<key removed>"
}
Дополнительные сведения см. в шаблоне параметров и конфигурации.
Установка SendGrid
В этом руководстве показано, как добавить Уведомления по электронной почте через SendGrid, но вы можете отправлять электронную почту с помощью SMTP и других механизмов.
SendGrid
Установите пакет NuGet:
В консоли диспетчер пакетов введите следующую команду:
Install-Package SendGrid
См. статью "Начало работы с SendGrid для бесплатной регистрации для бесплатной учетной записи SendGrid".
Реализация IEmailSender
Чтобы реализовать IEmailSender
, создайте Services/EmailSender.cs
код, аналогичный следующему:
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
namespace WebPWrecover.Services;
public class EmailSender : IEmailSender
{
private readonly ILogger _logger;
public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor,
ILogger<EmailSender> logger)
{
Options = optionsAccessor.Value;
_logger = logger;
}
public AuthMessageSenderOptions Options { get; } //Set with Secret Manager.
public async Task SendEmailAsync(string toEmail, string subject, string message)
{
if (string.IsNullOrEmpty(Options.SendGridKey))
{
throw new Exception("Null SendGridKey");
}
await Execute(Options.SendGridKey, subject, message, toEmail);
}
public async Task Execute(string apiKey, string subject, string message, string toEmail)
{
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("Joe@contoso.com", "Password Recovery"),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(toEmail));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
var response = await client.SendEmailAsync(msg);
_logger.LogInformation(response.IsSuccessStatusCode
? $"Email to {toEmail} queued successfully!"
: $"Failure Email to {toEmail}");
}
}
Настройка запуска для поддержки электронной почты
Добавьте следующий код в ConfigureServices
метод в Startup.cs
файле:
- Добавьте
EmailSender
в качестве временной службы. AuthMessageSenderOptions
Зарегистрируйте экземпляр конфигурации.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using WebPWrecover.Data;
using WebPWrecover.Services;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Шаблон RegisterConfirmation
Следуйте инструкциям по шаблону Identity и шаблону Account\RegisterConfirmation
.
Отключение проверки учетной записи по умолчанию при создании шаблонов account.RegisterConfirmation
Этот раздел применяется только при Account.RegisterConfirmation
создании шаблонов. Пропустите этот раздел, если вы не создали шаблон Account.RegisterConfirmation
.
Пользователь перенаправляется на Account.RegisterConfirmation
место, где можно выбрать ссылку, чтобы подтвердить учетную запись. Значение по умолчанию Account.RegisterConfirmation
используется только для тестирования, автоматическая проверка учетной записи должна быть отключена в рабочем приложении.
Чтобы требовать подтвержденную учетную запись и предотвратить немедленный вход при регистрации, задайте DisplayConfirmAccountLink = false
в шаблонном /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
файле:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
namespace WebPWrecover.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string Email { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public bool DisplayConfirmAccountLink { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
returnUrl = returnUrl ?? Url.Content("~/");
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
}
Этот шаг необходим только при Account.RegisterConfirmation
создании шаблонов. Нестандартная регистрация RegisterConfirmation автоматически обнаруживает, когда IEmailSender была реализована и зарегистрирована в контейнере внедрения зависимостей.
Регистрация, подтверждение электронной почты и сброс пароля
Запустите веб-приложение и проверьте поток подтверждения учетной записи и восстановления паролей.
- Запустите приложение и зарегистрируйте нового пользователя
- Проверьте электронную почту по ссылке подтверждения учетной записи. Если вы не получите сообщение электронной почты, просмотрите отладочную почту .
- Щелкните ссылку, чтобы подтвердить сообщение электронной почты.
- Войдите с помощью электронной почты и пароля.
- Выйти.
Тестирование сброса пароля
- Если вы вошли в систему, выберите "Выйти".
- Выберите ссылку "Войти" и щелкните ссылку "Забыл пароль"?
- Введите сообщение электронной почты, которое вы использовали для регистрации учетной записи.
- Отправляется сообщение электронной почты со ссылкой на сброс пароля. Проверьте электронную почту и щелкните ссылку, чтобы сбросить пароль. После успешного сброса пароля вы можете войти с помощью электронной почты и нового пароля.
Подтверждение повторной отправки электронной почты
В ASP.NET Core 5.0 и более поздних версий выберите ссылку подтверждения повторной отправки электронной почты на странице входа .
Изменение времени ожидания электронной почты и действий
Время ожидания бездействия по умолчанию — 14 дней. Следующий код задает время ожидания бездействия в течение 5 дней:
services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
Изменение срока жизни маркера защиты данных
Следующий код изменяет период ожидания всех маркеров защиты данных на 3 часа:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(
options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.Configure<DataProtectionTokenProviderOptions>(o =>
o.TokenLifespan = TimeSpan.FromHours(3));
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddRazorPages();
}
Встроенные Identity маркеры пользователей (см . раздел AspNetCore/src/IdentityExtensions.Core/src/TokenOptions.cs )имеют однодневное время ожидания.
Изменение срока жизни маркера электронной почты
Срок действия маркера по умолчанию для маркеров Identity пользователя составляет один день. В этом разделе показано, как изменить срок жизни маркера электронной почты.
Добавление пользовательского DataProtectorTokenProvider<TUser> и DataProtectionTokenProviderOptions:
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 void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.Tokens.ProviderMap.Add("CustomEmailConfirmation",
new TokenProviderDescriptor(
typeof(CustomEmailConfirmationTokenProvider<IdentityUser>)));
config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";
}).AddEntityFrameworkStores<ApplicationDbContext>();
services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>();
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddRazorPages();
}
Отладка электронной почты
Если вы не можете получить электронную почту, выполните следующие действия:
- Задайте точку останова для
EmailSender.Execute
проверкиSendGridClient.SendEmailAsync
. - Создайте консольное приложение для отправки электронной почты с помощью аналогичного кода
EmailSender.Execute
. - Просмотрите страницу действия электронной почты.
- Проверьте папку нежелательной почты.
- Попробуйте другой псевдоним электронной почты в другом поставщике электронной почты (Microsoft, Yahoo, Gmail и т. д.)
- Попробуйте отправить в разные учетные записи электронной почты.
Рекомендуется не использовать рабочие секреты в тестировании и разработке. При публикации приложения в Azure задайте секреты SendGrid в качестве параметров приложения на портале веб-приложения Azure. Система конфигурации настроена для чтения ключей из переменных среды.
Объединение учетных записей для входа в социальных сетях и локальных учетных записей входа
Чтобы завершить этот раздел, необходимо сначала включить внешний поставщик проверки подлинности. Ознакомьтесь с проверкой подлинности Facebook, Google и внешним поставщиком.
Вы можете объединить локальные и социальные учетные записи, щелкнув ссылку электронной почты. В следующей последовательности "RickAndMSFT@gmail.com" сначала создается в качестве локального входа. Однако сначала можно создать учетную запись в качестве имени входа в социальных сетях, а затем добавить локальное имя входа.
Щелкните ссылку "Управление ". Обратите внимание на внешние (социальные имена входа), связанные с этой учетной записью.
Щелкните ссылку на другую службу входа и примите запросы приложения. На следующем изображении Facebook является внешним поставщиком проверки подлинности:
Две учетные записи были объединены. Вы можете войти с помощью любой учетной записи. Возможно, вы хотите, чтобы пользователи добавляли локальные учетные записи в случае, если служба проверки подлинности в социальных сетях отключена, или, скорее всего, они потеряли доступ к своей учетной записи социальных параметров.
Включение подтверждения учетной записи после того, как сайт имеет пользователей
Включение подтверждения учетной записи на сайте с пользователями блокирует всех существующих пользователей. Существующие пользователи заблокированы, так как их учетные записи не подтверждены. Чтобы обойти существующую блокировку пользователей, используйте один из следующих подходов:
- Обновите базу данных, чтобы пометить всех существующих пользователей как подтвержденных.
- Подтвердите существующих пользователей. Например, пакетная отправка сообщений электронной почты с ссылками подтверждения.
ASP.NET Core