Asp.net Core Email подтверждение иногда говорит InvalidToken - PullRequest
0 голосов
/ 03 февраля 2019

Я использую идентификацию ядра asp.net 2.1, и у меня возникает случайная проблема с подтверждением по электронной почте, которое при подтверждении по электронной почте иногда говорит result.Error = InvalidToken .Токен также не имеет срока действия.

Примечание: Мы используем несколько серверов , и мы также сохранили наши ключи в одном месте, чтобы все серверы использовалите же ключи.

Фрагмент кода для подтверждения по электронной почте.

Подтверждение по электронной почте

var confCode = await _userManager.GenerateEmailConfirmationTokenAsync(user);
        var callbackUrl = Url.Action("ConfirmEmail", "Account", new
        {
            userId = user.Id,
            code = WebUtility.UrlEncode(confCode)
        }, protocol: HttpContext.Request.Scheme);

        string confirmationEmailBody = string.Format(GetTranslatedResourceString("ConfirmationEmailBody"), "<a href='" + callbackUrl + "'>") + "</a>";

Проверка токена

public async Task<bool> ConfirmEmailAsync(string userId, string code)
    {
        if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(code))
            return false;


        var user = await _userManager.FindByIdAsync(userId);

        if (user == null)
            return false;

        var result = await _userManager.ConfirmEmailAsync(user, code).ConfigureAwait(false);

        if (!result.Succeeded)
            result = await _userManager.ConfirmEmailAsync(user, WebUtility.UrlDecode(code)).ConfigureAwait(false);

        return result.Succeeded;
    }

Неверный токен

Код ниже указан дважды, но мы справимся с этой ситуацией

CfDJ8HYrrpCgcr5GvrItPOWapXRy8WF8odd%252BVKuDup7buRsl1x4agRpfgQlEIPWiBqM0Wuilu9tCv5l%252B3lNaAb89%252Fi%252B4k0y%252FH0jdXAbabz0%252FXDGA0eUrmcKdIsDFNuXeyP5ezTVmTx8t0ky9xCTXaKLAfvTsCJviETk5Ag9JbUs3l3%252BnUon6fyYOHsslJI5VKLqhMM0Sm%252BW1EE%252B%252FPEJ%252BXcn%252FPS1My%252BI1lExuF1R1hFEZScEsUCG%252Bx%252BVIFB9bzs1IoLC%252Baw%253D%253D

Любая помощь будет оценена, спасибо!

Ответы [ 7 ]

0 голосов
/ 15 февраля 2019

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

Возможны две проблемы:

Проблема 1: Оригинальная Base-64 не восстанавливается после HtmlDecode / UrlDecode

Эти токены кодируются в виде строк base 64, которые могут содержать такие символы, как '+'.

Они отправляются на сервер.

Затем сервер пытается выполнить операцию HtmlDecode над этой строкой, чтобы удалить символы, которые фактически присутствовали в оригинальном маркере base 64.

Например, '+' заменяется пустой строкой.

Итак, токен, сгенерированный после WebUtility.HtmlDecode, недействителен.Вот почему вы получаете недопустимую ошибку токена

How to check this ? Вы можете отладить и посмотреть, каково значение после HtmlDecode и какое ожидаемое значение.Если они различаются, то это основная причина.

Проблема 2: неправильно сформирована строка запроса

Несколько пар значений ключа в строках запроса объединяются с помощью символа '&',Например, key1 = value1 & key2 = value2

Но иногда вместо & в строку запроса входит его кодированная версия &amp;.
Например, key1 = value1 & key2 = value2

.Сетевой сервер не сможет правильно проанализировать строку запроса, если это так.

How to check this ? Вы можете использовать непосредственное чтение необработанной строки запроса из HttpContext или HttpRequest, используя свойство QueryString, и проверьте, так ли это.Если это так, вы можете либо изменить свой клиент для отправки соответствующей строки запроса (более логичной и поддерживаемой), либо написать некоторый код, чтобы исправить это на стороне сервера.

Эти указатели должны помочь вам решить проблему.

0 голосов
/ 19 февраля 2019

Если ваш закодированный код в конце содержит «==».т. е. после кодирования urlencode или base64, если код выглядит так: «cm9vdA ==».

декодирование не даст вам точную закодированную строку и приведет к неверному коду.

при генерации токена проверьте, заканчивается ли закодированное значение на "==".Если он генерирует другой токен, и проблема будет решена.

0 голосов
/ 11 февраля 2019

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

Когда пользовательский реестр добавляет два столбца в вашу пользовательскую таблицу.Один для проверки и другие для IsVerified.В столбец токена проверки добавьте Guid.Затем создайте ссылку с этим Guid.Когда пользователь нажимает эту ссылку, вы получаете Guid внутри контроллера.Затем получите этого пользователя, используя этот столбец, затем установите для столбца IsVerified значение true и удалите столбец Guid.И ваш пользователь теперь успешно подтвержден.

0 голосов
/ 09 февраля 2019

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

0 голосов
/ 07 февраля 2019

Вы должны декодировать код подтверждения перед передачей его в метод _userManager.ConfirmEmailAsync(user, code).ConfigureAwait(false).

У вас есть URL, закодированный кодом подтверждения, который вы используете в callBackUrl;Вы должны использовать WebUtility.UrlDecode(code) для декодирования, прежде чем пытаться его использовать.

0 голосов
/ 04 февраля 2019

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

    services.AddIdentity<ApplicationUser, ApplicationRole>(options => {
        options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
        options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
    }).AddDefaultTokenProviders()
    .AddEntityFrameworkStores<YourDbContext>();
0 голосов
/ 03 февраля 2019

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

...