Проверка личности по электронной почте не работает после вызова GenerateChangePhoneNumberTokenAsync()

Недавно я получаю сообщение об ошибке «Неверный токен» при проверке электронной почты с использованием идентификатора asp.net.

У меня есть сложный поток, как показано ниже:

Всякий раз, когда пользователь регистрируется, система отправляет электронное письмо для подтверждения учетной записи.

string emailConfirmationToken = await _userManager.GenerateEmailConfirmationTokenAsync(userId);

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

string phoneNumberVerifyCode = await _userManager.GenerateChangePhoneNumberTokenAsync(loginUserId, model.phone);

Проблема заключается в том, что если пользователь сначала подтвердит номер телефона, а затем подтвердит сообщение электронной почты с сообщением об ошибке «токен недействителен», а если пользователь сначала подтвердит адрес электронной почты, то «код номера телефона недействителен».

Не могли бы вы помочь мне в этом?

Заранее спасибо!


person Sadik Ali    schedule 19.07.2019    source источник


Ответы (1)


У меня были аналогичные проблемы при создании сообщений электронной почты и SMS сразу после создания учетной записи пользователя. Подтверждение электронной почты завершится ошибкой, если сначала будет подтвержден телефон. Однако, если сначала была проверена электронная почта, в моем случае проверка по SMS все еще работала.

Что я в итоге сделал (что имеет больше смысла с точки зрения безопасности учетной записи), так это не отправлял подтверждение по электронной почте до тех пор, пока не будет проверен телефонный код. Таким образом, каждый раз, когда кто-то меняет свой номер телефона, я принудительно повторно подтверждаю адрес электронной почты, так как это уведомляет пользователя об изменениях (в случае сим-атаки он получает электронное письмо) и поддерживает второй метод связи.

Я помещаю создание E-mail в метод проверки SMS:

protected void Code_Click(object sender, EventArgs e)
{
    if (!ModelState.IsValid)
    {
        ModelState.AddModelError("", "Invalid code");
        return;
    }

    var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
    var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>();

    var result = manager.ChangePhoneNumber(User.Identity.GetUserId(), PhoneNumber.Value, Code.Text);

    if (result.Succeeded)
    {
        var userInfo = manager.FindById(User.Identity.GetUserId());

        if (userInfo != null)
        {
            signInManager.SignIn(userInfo, isPersistent: false, rememberBrowser: false);
            // force 2FA login with successful phone number
            manager.SetTwoFactorEnabled(User.Identity.GetUserId(), true);

            // force new cell phone changes to un-confirm & re-verify email for security reasons
            userInfo.EmailConfirmed = false;
            var EmCode = manager.GenerateEmailConfirmationToken(User.Identity.GetUserId());
            var callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(EmCode, User.Identity.GetUserId(), Request);
            manager.SendEmail(User.Identity.GetUserId(), "Confirm your account", "A phone number has been added to your account. For security reasons, please confirm your email by clicking <a href=\"" + callbackUrl + "\">here</a>.");

            Response.Redirect("/Account/Manage?m=AddPhoneNumberSuccess");
        }
    }

    ModelState.AddModelError("", "Failed to verify phone");
}

Вы также можете сделать обратное и поместить отправку SMS-кода в метод проверки электронной почты, если проверка электронной почты была важнее, чем SMS, но вы хотели и то, и другое. В моем случае номер телефона был важнее электронной почты, поэтому он имел приоритет при регистрации.

Теперь, когда я оглядываюсь на это, я рад, что это не сработало так, как я изначально планировал, поскольку этот метод более прост, и пользователь с меньшей вероятностью забудет сделать то или иное. Это решение проводит их через него, а не бомбардирует пользователя задачами.

person swimex    schedule 06.10.2019