Stack Exchange
Asp.net core Identity Password reset "invalid token" even though tokens generated are identical
I am on Asp.Net core with .Net 5.0 In startup I have added;
        services.AddIdentity<ApplicationUser, ApplicationRole>(SetupIdentityOptions)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        
        services.Configure<DataProtectionTokenProviderOptions>(opt => 
            {
                opt.TokenLifespan = TimeSpan.FromDays(1);
            }
        );

I generate the code as below(encoding done as per the MS docs);
            var code = await CommonServices.UserManager.GeneratePasswordResetTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));

            var callbackUrl = $"{request.RequestData.ReturnUrl}?code={code}";

Now if I save the code generated at this point and check the code received to controller after user clicks the link they are identical. However when I do;
var result = await CS.UserManager.ResetPasswordAsync(user, model.Code, model.Password);

it gives me "Invalid Token" however tokens are identical.
Then I tried this and still says invalid token;
var isValidToken = await _userManager.VerifyUserTokenAsync(
user,
_userManager.Options.Tokens.PasswordResetTokenProvider,
UserManager<TUser>.ResetPasswordTokenPurpose,
code);

I am not sure whether the Identity framework saves the generated tokens in [AspNetUserTokens] table. I can't find any saved tokens after a generating the token.
What may be the problem?

My bad, I had to convert the encoded string back which I haven't done.
So, since I used
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));

After user clicks the link, I have to;
var bytes = WebEncoders.Base64UrlDecode(model.Code);
var code = Encoding.UTF8.GetString(bytes);

and then call
ResetPasswordAsync(user, code, model.Password);

which worked
