chỉ lưu trữ & quản lý dữ liệu email của User, không gửi email đi đâu cả

✅ Nó LÀM:

  • Lưu email vào database
  • Lấy email của user
  • Lưu trạng thái EmailConfirmed
  • Tìm user theo email

❌ Nó KHÔNG LÀM:

  • Gửi email
  • Tạo nội dung email
  • Gửi link xác nhận
  • Gửi OTP / reset password

1. IUserEmailStore<TUser> là gì?

IUserEmailStore<TUser>interface dùng để quản lý Email của User trong ASP.NET Core Identity.

Nó cho phép hệ thống:

  • Lưu email người dùng
  • Lấy email
  • Kiểm tra email đã xác nhận chưa
  • Set trạng thái xác nhận email

👉 Identity dùng interface này để không phụ thuộc vào database cụ thể (SQL, MongoDB, In-memory, v.v.).


2. IUserEmailStore dùng để làm gì?

Một số chức năng chính:

  • Đăng nhập bằng email
  • Xác nhận email (Email Confirmation)
  • Reset mật khẩu qua email
  • Kiểm tra email có tồn tại chưa

3. Các method quan trọng

public interface IUserEmailStore<TUser> : IUserStore<TUser>
{
    Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken);
    Task<string> GetEmailAsync(TUser user, CancellationToken cancellationToken);

    Task<bool> GetEmailConfirmedAsync(TUser user, CancellationToken cancellationToken);
    Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken);

    Task<TUser> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken);
    Task<string> GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken);
    Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken);
}

4. UserEmailStore nằm ở đâu trong project thực tế?

Nếu bạn dùng Identity mặc định (Entity Framework):

services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

👉 Lúc này:

  • UserManager tự động dùng UserStore
  • UserStore đã implement sẵn IUserEmailStore

Bạn không cần tự viết UserEmailStore.

5. Khi nào cần tự implement IUserEmailStore?

Bạn cần tự implement nếu:

  • Không dùng Entity Framework
  • Dùng database riêng (MongoDB, API, file, v.v.)
  • Muốn custom cách lưu User

Ví dụ:

public class CustomUserStore :
    IUserStore<ApplicationUser>,
    IUserEmailStore<ApplicationUser>
{
    public Task SetEmailAsync(ApplicationUser user, string email, CancellationToken ct)
    {
        user.Email = email;
        return Task.CompletedTask;
    }

    public Task<string> GetEmailAsync(ApplicationUser user, CancellationToken ct)
    {
        return Task.FromResult(user.Email);
    }

    public Task<bool> GetEmailConfirmedAsync(ApplicationUser user, CancellationToken ct)
    {
        return Task.FromResult(user.EmailConfirmed);
    }

    public Task SetEmailConfirmedAsync(ApplicationUser user, bool confirmed, CancellationToken ct)
    {
        user.EmailConfirmed = confirmed;
        return Task.CompletedTask;
    }

    // Các method khác bắt buộc phải implement...
}

6. Quan hệ với UserManager

UserManager<TUser> sẽ gọi IUserEmailStore ở bên dưới:

await _userManager.SetEmailAsync(user, "test@gmail.com");
await _userManager.IsEmailConfirmedAsync(user);

👉 Bạn không gọi trực tiếp UserEmailStore, mà gọi qua UserManager.