ASP.NET Core의 계정 확인 및 암호 복구 Blazor
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
Important
이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.
현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
이 문서에서는 전자 메일 확인 및 암호 복구를 사용하여 ASP.NET Core Blazor Web App 를 구성하는 방법을 설명합니다.
참고 항목
이 문서는 s에 Blazor Web App만 적용됩니다. ASP.NET Core를 사용하여 독립 실행형 Blazor WebAssembly 앱에 대한 이메일 확인 및 암호 복구를 구현하려면 ASP.NET CoreIdentity를 사용하여 ASP.NET Core Blazor WebAssembly Identity에서 계정 확인 및 암호 복구를 참조하세요.
네임스페이스
이 문서의 예제에서 사용하는 앱의 네임스페이스는 다음과 같습니다 BlazorSample
. 앱의 네임스페이스를 사용하도록 코드 예제를 업데이트합니다.
전자 메일 공급자 선택 및 구성
이 문서에서 Mailchimp의 트랜잭션 API는 Mandrill.net 통해 이메일을 보내는 데 사용됩니다. 메일 서비스를 사용하여 SMTP 대신 전자 메일을 보내는 것이 좋습니다. SMTP는 제대로 구성하고 보호하기가 어렵습니다. 사용하는 전자 메일 서비스 중에서 .NET 앱에 대한 지침에 액세스하고, 계정을 만들고, 해당 서비스에 대한 API 키를 구성하고, 필요한 NuGet 패키지를 설치합니다.
비밀 전자 메일 공급자 API 키를 보유하는 클래스를 만듭니다. 이 문서의 예제에서는 속성을 가진 명명된 AuthMessageSenderOptions
클래스를 EmailAuthKey
사용하여 키를 보유합니다.
AuthMessageSenderOptions.cs
:
namespace BlazorSample;
public class AuthMessageSenderOptions
{
public string? EmailAuthKey { get; set; }
}
AuthMessageSenderOptions
파일에 구성 인스턴스를 등록합니다.Program
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration);
공급자의 보안 키에 대한 사용자 암호 구성
프로젝트가 Secret Manager 도구에 대해 이미 초기화된 경우 프로젝트 파일()에 앱 비밀 식별자(<AppSecretsId>
.csproj
)가 이미 있습니다. Visual Studio에서는 솔루션 탐색기 프로젝트를 선택할 때 속성 패널을 확인하여 앱 비밀 ID가 있는지 확인할 수 있습니다. 앱이 초기화되지 않은 경우 프로젝트 디렉터리에 열린 명령 셸에서 다음 명령을 실행합니다. Visual Studio에서 개발자 PowerShell 명령 프롬프트를 사용할 수 있습니다.
dotnet user-secrets init
Secret Manager 도구를 사용하여 API 키를 설정합니다. 다음 예제에서 키 이름은 EmailAuthKey
일치 AuthMessageSenderOptions.EmailAuthKey
하며 키는 자리 표시자로 표시됩니다 {KEY}
. API 키를 사용하여 다음 명령을 실행합니다.
dotnet user-secrets set "EmailAuthKey" "{KEY}"
Visual Studio를 사용하는 경우 솔루션 탐색기 서버 프로젝트를 마우스 오른쪽 단추로 클릭하고 사용자 비밀 관리를 선택하여 비밀이 설정되었는지 확인할 수 있습니다.
자세한 내용은 ASP.NET Core에서 개발 중인 앱 비밀 보안 스토리지를 참조하세요.
Warning
앱 비밀, 연결 문자열, 자격 증명, 암호, PIN(개인 식별 번호), 개인 C#/.NET 코드 또는 프라이빗 키/토큰을 항상 안전하지 않은 클라이언트 쪽 코드에 저장하지 마세요. 테스트/스테이징 및 프로덕션 환경에서 서버 쪽 Blazor 코드 및 웹 API는 프로젝트 코드 또는 구성 파일 내에서 자격 증명을 유지 관리하지 않는 보안 인증 흐름을 사용해야 합니다. 로컬 개발 테스트 외에는 환경 변수가 가장 안전한 방법이 아니므로 환경 변수를 사용하여 중요한 데이터를 저장하는 것을 피하는 것이 좋습니다. 로컬 개발 테스트의 경우 중요한 데이터를 보호하기 위해 Secret Manager 도구를 사용하는 것이 좋습니다. 자세한 내용은 중요한 데이터 및 자격 증명을 안전하게 유지 관리하세요.
도구 IEmailSender
다음 예제는 Mandrill.net 사용하는 Mailchimp의 트랜잭션 API를 기반으로 합니다. 다른 공급자의 경우 전자 메일 메시지 보내기를 구현하는 방법에 대한 설명서를 참조하세요.
프로젝트에 Mandrill.net NuGet 패키지를 추가합니다.
다음 EmailSender
클래스를 추가하여 구현 IEmailSender<TUser>합니다. 다음 예제 ApplicationUser
에서는 .입니다 IdentityUser. 메시지 HTML 태그를 추가로 사용자 지정할 수 있습니다. 전달된 MandrillMessage
문자가 message
문자로 <
시작하는 한 Mandrill.net API는 메시지 본문이 HTML로 구성되어 있다고 가정합니다.
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(AppUser user, string email,
string confirmationLink) => SendEmailAsync(email, "Confirm your email",
"<html lang=\"en\"><head></head><body>Please confirm your account by " +
$"<a href='{confirmationLink}'>clicking here</a>.</body></html>");
public Task SendPasswordResetLinkAsync(AppUser user, string email,
string resetLink) => SendEmailAsync(email, "Reset your password",
"<html lang=\"en\"><head></head><body>Please reset your password by " +
$"<a href='{resetLink}'>clicking here</a>.</body></html>");
public Task SendPasswordResetCodeAsync(AppUser user, string email,
string resetCode) => SendEmailAsync(email, "Reset your password",
"<html lang=\"en\"><head></head><body>Please reset your password " +
$"using the following code:<br>{resetCode}</body></html>");
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);
}
}
참고 항목
메시지의 본문 콘텐츠에는 전자 메일 서비스 공급자에 대한 특별한 인코딩이 필요할 수 있습니다. 전자 메일 메시지에서 메시지 본문의 링크를 따를 수 없는 경우 서비스 공급자의 설명서를 참조하여 문제를 해결합니다.
전자 메일을 지원하도록 앱 구성
파일에서 Program
이메일 보낸 사람 구현을 다음으로 EmailSender
변경합니다.
- builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
+ builder.Services.AddSingleton<IEmailSender<ApplicationUser>, EmailSender>();
앱에서 IdentityNoOpEmailSender
(Components/Account/IdentityNoOpEmailSender.cs
)를 제거합니다.
RegisterConfirmation
구성 요소(Components/Account/Pages/RegisterConfirmation.razor
)에서 다음 항목이 있는지 EmailSender
IdentityNoOpEmailSender
확인하는 블록의 @code
조건부 블록을 제거합니다.
- else if (EmailSender is IdentityNoOpEmailSender)
- {
- ...
- }
또한 구성 요소에서 RegisterConfirmation
필드를 검사하기 emailConfirmationLink
위한 태그 및 코드를 제거하고 Razor 사용자에게 전자 메일을 확인하도록 지시하는 줄만 남겨 두세요.
- @if (emailConfirmationLink is not null)
- {
- ...
- }
- else
- {
<p>Please check your email to confirm your account.</p>
- }
@code {
- private string? emailConfirmationLink;
...
}
사이트에 사용자가 있을 때 계정 확인 사용
사용자가 있는 사이트에서 계정 확인을 활성화하면 기존 사용자가 모두 잠깁니다. 기존 사용자는 계정이 확인되지 않으므로 잠겨 있습니다. 기존 사용자 잠금을 해결하려면 다음 방법 중 하나를 사용합니다.
- 모든 기존 사용자를 확인됨으로 표시하도록 데이터베이스를 업데이트합니다.
- 기존 사용자를 확인합니다. 예를 들어 확인 링크가 있는 이메일을 일괄 처리로 보냅니다.
전자 메일 및 활동 시간 제한
기본 비활성 시간 제한은 14일입니다. 다음 코드는 슬라이딩 만료가 있는 비활성 시간 제한을 5일로 설정합니다.
builder.Services.ConfigureApplicationCookie(options => {
options.ExpireTimeSpan = TimeSpan.FromDays(5);
options.SlidingExpiration = true;
});
모든 ASP.NET Core Data Protection 토큰 수명 변경
다음 코드는 Data Protection 토큰의 제한 시간을 3시간으로 변경합니다.
builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
options.TokenLifespan = TimeSpan.FromHours(3));
기본 제공 Identity 사용자 토큰(AspNetCore/src//IdentityExtensions.Core/src/TokenOptions.cs)에는 1일 제한 시간이 있습니다.
참고 항목
.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.
이메일 토큰 수명 변경
사용자 토큰의 Identity 기본 토큰 수명은 1일입니다.
참고 항목
.NET 참조 원본의 설명서 링크는 일반적으로 다음 릴리스의 .NET을 위한 현재 개발을 나타내는 리포지토리의 기본 분기를 로드합니다. 특정 릴리스를 위한 태그를 선택하려면 Switch branches or tags(분기 또는 태그 전환) 드롭다운 목록을 사용합니다. 자세한 내용은 ASP.NET Core 소스 코드(dotnet/AspNetCore.Docs #26205)의 버전 태그를 선택하는 방법을 참조하세요.
전자 메일 토큰 수명을 변경하려면 사용자 지정 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);
}
}
파일에서 사용자 지정 토큰 공급자 Program
를 사용하도록 서비스를 구성합니다.
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>>();
문제 해결
이메일을 사용할 수 없는 경우:
EmailSender.Execute
에서 중단점을 설정하여SendEmailAsync
가 호출되는지 확인합니다.- 문제를 디버그하는 것과 유사한 코드를 사용하여 전자 메일을
EmailSender.Execute
보내는 콘솔 앱을 만듭니다. - 전자 메일 공급자의 웹 사이트에서 계정 전자 메일 기록 페이지를 검토합니다.
- 스팸 폴더에서 메시지를 확인합니다.
- Microsoft, Yahoo 또는 Gmail과 같은 다른 전자 메일 공급자에서 다른 전자 메일 별칭을 사용해 보세요.
- 다른 이메일 계정으로 전송해 보세요.
추가 리소스
ASP.NET Core