I have a .net 6 application with Identity for authentication handling. In a reset password endpoint, I'm struggling with a "Invalid token" error from Identity.
Token generation service:
public async Task AskPasswordReset(string email)
{
var user = await _userManager.FindByEmailAsync(email);
if (user != null)
{
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var confirmationLink = _configuration["Base Url"] + "/ResetPassword?token=" + token + "&email=" + email;
var emailAddress = email;
var confimEmail = new EmailCommunicationDto
{
To = emailAddress,
Body = $"You have a requested to reset you password. Please click the link provided to reset your password. Please click " + confirmationLink + " to reset.",
Subject = "Password Reset"
};
await _emailSender.SendVerificationEmail(confimEmail);
}
}
Token reset service:
public async Task ResetPassword(ResetPasswordDto resetPasswordDto)
{
var user = await _userManager.FindByEmailAsync(resetPasswordDto.email);
if (user == null)
{
throw new NotFoundException();
}
var result = await _userManager.ResetPasswordAsync(user, resetPasswordDto.token, resetPasswordDto.newPassword);
if (!result.Succeeded)
{
Console.WriteLine(result.ToString());
throw new InvalidCredentialsException();
}
}
Generated email:
You have a requested to reset you password. Please click the link provided to reset your password. Please click https://localhost:3000/ResetPassword?token=CfAA8KTxCSxQvlpEtzGh0VfCOQoKfuszpNPEK/yXBxCLkB2iC07vDNHecXedk6GFdl/ZlO8oqxxDNrVjj5ZdiPCXdpleOcfU2+utrCm7MLqlEWQYfx6RvAlmLRgKwcrIqVE1kXLqEGvdumAgDYYfCw0m5RosDgf0JlW3fthpbQWgIe5CoOl9UWJV20gdl2hVgh95wLhRV7WfWNTXSYv28K9ZQk31YzOhNaFjmgqXOSHAgTI2&[email protected] to reset.
Reset password DTO:
{ "newPassword": "joijoji9**Koji", "token": "CfAA8KTxCSxQvlpEtzGh0VfCOQoKfuszpNPEK/yXBxCLkB2iC07vDNHecXedk6GFdl/ZlO8oqxxDNrVjj5ZdiPCXdpleOcfU2 utrCm7MLqlEWQYfx6RvAlmLRgKwcrIqVE1kXLqEGvdumAgDYYfCw0m5RosDgf0JlW3fthpbQWgIe5CoOl9UWJV20gdl2hVgh95wLhRV7WfWNTXSYv28K9ZQk31YzOhNaFjmgqXOSHAgTI2", "email": "[email protected]" }
1st guess: When the token is gotten from the url (I'm using React), there is a decoding that alters it. 2nd guess: Identity only allows password reset after email verification
Your first guess looks promising to me, since the token you're appending in your URL contains special characters like '/'.
Try encoding the token before appending it, with something like
token = Base64UrlEncoder.Encode(token);
var confirmationLink = _configuration["Base Url"] + "/ResetPassword?token=" + token + "&email=" + email;