Подтверждение Email в ASP.NET Identity 2.0

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

В статье Подтверждение регистрации по Email рассматривался общий механизм подтверждения регистрации по электронной почте, главным образом, применительно к ASP.NET Identity 1.0. В Identity 2.0 этот процесс будет немного отличаться, хотя суть будет та же.

Итак, создадим новый проект ASP.NET MVC 5 с типом аутентификации Individual User Accounts. Он по умолчанию содержит весь инструментарий для авторизации: модели, контроллер и представления.

Теперь если мы используем в проекте ASP.NET Identity 2, то модель, представляющая пользователя в системе, уже имеет необходимые свойства: свойство Email для хранения адреса электронной почты и булевое свойство EmailConfirmed, которое показывает, подтвержден ли электронный адрес.

В ASP.NET Identity 2 имеется уже вся необходимая инфраструктура для создания регистрации через электронную почту. Так, модель и представление регистрации настроены на принятия электронного адреса в качестве логина. Поэтому перейдем к контроллеру AccountController.

В контроллере AccountController изменим метод Register, обрабатывающий post-запросы, таким образом, чтобы при регистрации он мог посылать сообщения на электронную почту:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            // генерируем токен для подтверждения регистрации
            var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
			// создаем ссылку для подтверждения
            var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code },
                       protocol: Request.Url.Scheme);
			// отправка письма
            await UserManager.SendEmailAsync(user.Id, "Подтверждение электронной почты",
                       "Для завершения регистрации перейдите по ссылке:: <a href=\""
                                                       + callbackUrl + "\">завершить регистрацию</a>");
            return View("DisplayEmail");
        }
        AddErrors(result);
    }
	return View(model);
}

Вначале нам надо сгенерировать некий токен для подтверждения email с помощью метода UserManager.GenerateEmailConfirmationTokenAsync

И затем сформированное сообщение с ссылкой отправляется на email пользователя с помощью метода UserManager.SendEmailAsync. Эта ссылка указывает на метод ConfirmEmail.

В случае удачной отправки письма пользователю отправляется представление DisplayEmail, которое мы сейчас добавим. Оно будет просто будет уведомлять пользователя, что действие завершилось успешно:

@{
    ViewBag.Title = "Завершение регистрации";
}

<h2>@ViewBag.Title</h2>

<p>На указанный электронный адрес отправлены дальнейшие инструкции по завершению регистрации</p>

Однако возникает вопрос, как это все отправляется? Для этого перейдем в файле IdentityConfig.cs, который находится в папке App_Start. Здесь определен следующий класс:

public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // Plug in your email service here to send an email.
        return Task.FromResult(0);
    }
}

Этот класс используется для установки почтовых реквизитов и прочей информации, связанной с отправкой электронной почты. В том же файле в методе Create мы можем найти установку этого сервиса в качестве службы для отправки почтовых сообщений:

public static ApplicationUserManager Create( 
						IdentityFactoryOptions<ApplicationUserManager> options, 
						IOwinContext context) 
{
     var manager = new ApplicationUserManager( 
				new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
    //..........................
    manager.EmailService = new EmailService();
    manager.SmsService = new SmsService();
	//.........................
}

Таким образом, для настройки отправки почтовых сообщений нам надо настроить класс EmailService. Для этого в начало файла IdentityConfig.cs подключим пространство имен System.Net.Mail, которое предоставляет функциональность для отправки почты.

Далее изменим класс EmailService следующим образом:

public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // настройка логина, пароля отправителя
        var from = "somemail@yandex.ru";
        var pass = "password12";

        // адрес и порт smtp-сервера, с которого мы и будем отправлять письмо
        SmtpClient client = new SmtpClient("smtp.yandex.ru", 25);

        client.DeliveryMethod = SmtpDeliveryMethod.Network;
		client.UseDefaultCredentials = false;
		client.Credentials = new System.Net.NetworkCredential(from, pass);
        client.EnableSsl = true;

        // создаем письмо: message.Destination - адрес получателя
        var mail = new MailMessage(from, message.Destination);
        mail.Subject = message.Subject;
        mail.Body = message.Body;
        mail.IsBodyHtml = true;

        return client.SendMailAsync(mail);
    }
}

Здесь производится стандартная для .NET отправка письма в асинхронном варианте. В итоге пользователь получит письмо с ссылкой.

Теперь надо также изменить метод Login, обрабатывающий post-запрос:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindAsync(model.Email, model.Password);
        if (user != null)
        {
            if (user.EmailConfirmed == true)
            {
                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Не подтвержден email.");
            }
		}
        else
        {
            ModelState.AddModelError("", "Неверный логин или пароль");
        }
    }
	return View(model);
}

Теперь при логине будет учитываться, подтвердил ли ранее пользователь свой email.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850