0

Sometimes i get "invalid token" for await _userManager.ConfirmEmailAsync(user, tokenDecode)

It comes right after user gets successful ConfirmEmail. Second Token looks like as if it has been decoded by HttpUtility.UrlDecode already.

But in most cases I get only one message with successful ConfirmEmail.

(ASP.NET Core 5.08)

private async Task SendConfirmationEmail(User user)
        {
            var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var htmlToken = HttpUtility.UrlEncode(token);
            var confirmationLink = Url.Action($"ConfirmUserEmail", $"User", new { token = htmlToken, email = user.Email }, Request.Scheme);
            *** Email send code ***           
        }
[AllowAnonymous]
[HttpGet("[action]")]
public async Task<IActionResult> ConfirmUserEmail(string token, string email)
{
    try
    {
        if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(token))
             return BadRequest(new { message = "Incorrect link" });
        var user = await _userManager.FindByEmailAsync(email);
        if (user == null) return BadRequest(new { message = "User not found" });

        var tokenDecode = HttpUtility.UrlDecode(token);

        var result = await _userManager.ConfirmEmailAsync(user, tokenDecode);

        var logMessage = $"Log email confirmation try{Environment.NewLine}" +
                         $"Date: {DateTimeOffset.Now}{Environment.NewLine}" +
                         $"User email: {user.Email}{Environment.NewLine}" +
                         $"token: {tokenDecode}{Environment.NewLine}" + 
                         $"Headers:{Environment.NewLine}";
        logMessage = HttpContext.Request.Headers.Aggregate(logMessage, (current, header) 
               => current + $"{header.Key}: {header.Value} {Environment.NewLine}");
        logMessage += "Result: " + (result.Succeeded ? "Success" : "Failed") + Environment.NewLine;
        if (!result.Succeeded)
            logMessage += "Reason: " + result.Errors.Aggregate("", (current, error) => current + error.Description);
        _logger.LogInformation(LogEvents.WithSendingEmail, logMessage);

        return Redirect(result.Succeeded ? Url.Content("/confirmedEmail") : Url.Content("/error"));
    }
    catch (Exception exception)
    {
        _logger.LogError(LogEvents.WithSendingEmail, exception, "");
        return Redirect(Url.Content("/error"));
    }
}

First log message:

Log email confirmation try
Date: 8/8/2021 8:08:58 AM +03:00
User email: <userEmail>@gmail.com
token: CfDJ8GTNMGFQaZhGlXgSrSNRbPNZFf4ESjdOq8O1hzO9jKG8b66k0nCJYH49Ko5BBEJeVNZBvXqrIgp2uE42bN2sj8yfU1flXgWR+CwfcX3M8548EI/l6eyt+hrgqVRw9+GIfSKrtWMcRl4h0UhULk2EPraQe5kESajPQeg7RTz+Izc0JEVqYAhM5TGGRDUlfba79DxeFixE8ulAJ95/7JZPn7L24RzZom8psJ7lNxUjoyDVeN8Jt48/utPBD81sgJJLzA==
Headers:
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Host: usselectro.so-online.ru
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Upgrade-Insecure-Requests: 1
X-Real-IP: 213.87.246.199
X-Original-Proto: http
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
X-Original-For: [::1]:56654
Result: Success

Second log message (which comes right after the first one):

Log email confirmation try
Date: 8/8/2021 8:09:13 AM +03:00
User email: <userEmail>@gmail.com
token: CfDJ8GTNMGFQaZhGlXgSrSNRbPNZFf4ESjdOq8O1hzO9jKG8b66k0nCJYH49Ko5BBEJeVNZBvXqrIgp2uE42bN2sj8yfU1flXgWR CwfcX3M8548EI/l6eyt hrgqVRw9 GIfSKrtWMcRl4h0UhULk2EPraQe5kESajPQeg7RTz Izc0JEVqYAhM5TGGRDUlfba79DxeFixE8ulAJ95/7JZPn7L24RzZom8psJ7lNxUjoyDVeN8Jt48/utPBD81sgJJLzA==
Headers:
Connection: close
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Host: usselectro.so-online.ru
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Upgrade-Insecure-Requests: 1
X-Real-IP: 31.129.192.164
X-Original-Proto: http
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
X-Original-For: 127.0.0.1:36098
Result: Failed
Reason: Invalid token.

Any ideas where second request to ConfirmUserEmail might come from?

1 Answers1

0

Could be their email client fetching a preview? This is why confirmation pages usually submit a POST request so that random software accessing the link doesn't cause changes :)

I've also seen spam filters accessing links to see where they go to.

juunas
  • 54,244
  • 13
  • 113
  • 149