下面是一个示例解决方案,演示了如何在ASP.NET Core MVC中实现两因素电子邮件确认(无身份验证)。
EmailConfirmation
模型来存储电子邮件确认信息:public class EmailConfirmation
{
public int Id { get; set; }
public string UserId { get; set; }
public string Token { get; set; }
public DateTime CreatedAt { get; set; }
}
IdentityUser
类的派生类中添加一个EmailConfirmed
属性,用于跟踪用户是否已确认电子邮件:public class ApplicationUser : IdentityUser
{
public bool EmailConfirmed { get; set; }
}
EmailConfirmationDbContext
类,用于处理电子邮件确认的数据库操作:public class EmailConfirmationDbContext : DbContext
{
public DbSet EmailConfirmations { get; set; }
public EmailConfirmationDbContext(DbContextOptions options) : base(options)
{
}
}
Startup.cs
文件的ConfigureServices
方法中配置Identity服务和电子邮件确认数据库上下文:public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
// ...
}
public class EmailService
{
private readonly IEmailSender _emailSender;
public EmailService(IEmailSender emailSender)
{
_emailSender = emailSender;
}
public async Task SendConfirmationEmail(ApplicationUser user, string confirmationLink)
{
await _emailSender.SendEmailAsync(user.Email, "Confirm your email",
$"Please confirm your email by clicking this link: link");
}
}
AccountController
中添加一个SendConfirmationEmail
方法,用于生成电子邮件确认链接并发送给用户:private readonly EmailConfirmationDbContext _emailConfirmationDbContext;
private readonly EmailService _emailService;
public AccountController(EmailConfirmationDbContext emailConfirmationDbContext, EmailService emailService)
{
_emailConfirmationDbContext = emailConfirmationDbContext;
_emailService = emailService;
}
[HttpGet]
[AllowAnonymous]
public async Task SendConfirmationEmail(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return NotFound();
}
var token = Guid.NewGuid().ToString();
var emailConfirmation = new EmailConfirmation
{
UserId = user.Id,
Token = token,
CreatedAt = DateTime.UtcNow
};
_emailConfirmationDbContext.EmailConfirmations.Add(emailConfirmation);
await _emailConfirmationDbContext.SaveChangesAsync();
var confirmationLink = Url.Action("ConfirmEmail", "Account",
new { userId = user.Id, token = token }, Request.Scheme);
await _emailService.SendConfirmationEmail(user, confirmationLink);
return Ok();
}
ConfirmEmail
方法,用于处理用户点击电子邮件确认链接的请求:[HttpGet]
[AllowAnonymous]
public async Task ConfirmEmail(string userId, string token)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return NotFound();
}
var emailConfirmation = await _emailConfirmationDbContext.EmailConfirmations
.SingleOrDefaultAsync(ec => ec.UserId == userId && ec.Token == token);
if (emailConfirmation == null)
{
return BadRequest();
}
emailConfirmation.EmailConfirmed = true;
_emailConfirmationDbContext.EmailConfirmations.Remove(emailConfirmation);
await _emailConfirmationDbContext.SaveChangesAsync();
return Ok();
}
EmailConfirmed
属性设置为false
,并