Reputation: 815
I have problem with resetting password for user account. I am using Microsoft way to do it, but it's just not working. Here is the code that I use to generate reset password token
var resetPasswordToken = new ResetPasswordToken
{
Id = Guid.NewGuid().ToString(),
Token = UserManager.GeneratePasswordResetToken(user.Id),
User = user,
ValidFrom = DateTime.Now,
ValidTo = DateTime.Now.AddMinutes(ApplicationConstants.SettingsResetPasswordTokensValidTimeInMinutes)
};
_resetPasswordTokensRepository.Insert(resetPasswordToken);
_resetPasswordTokensRepository.Save();
var email = new ResetPasswordEmailModel
{
ResetPasswordToken = resetPasswordToken,
User = user
};
IUserMailer mailer = new UserMailer();
mailer.ResetPassword(email).Send();
That works fine, I have the token in database and I send it to user via email. Then user has to click the link. Here is how I generate new password and replace old password with the new one in database.
var resetPasswordToken = _resetPasswordTokensRepository.GetByEmailAndToken(email, code);
var newPassword = Membership.GeneratePassword(10, 2);
var result = await UserManager.ResetPasswordAsync(user.Id, resetPasswordToken.Token, newPassword);
if (result.Succeeded)
{
_resetPasswordTokensRepository.Remove(resetPasswordToken);
_usersRepository.Save();
var model = new NewPasswordEmailModel
{
User = user,
Password = newPassword
};
IUserMailer mailer = new UserMailer();
mailer.NewPassword(model).Send();
}
And this also works. I mean it changes password in database and sends it to user via email. The problem is user can not login with the new password or with the old password. I did not show it here, but I check if both token and user exist in database.
What am I doing wrong?
Upvotes: 1
Views: 3995
Reputation: 35126
Despite that you already found the issue, I'll try to point in a better direction.
What you describe is not a "Microsoft" way. First time I see something like that. Is this part of a template? Open Visual Studio 2013 and create a new MVC project with Individual Accounts - this will give you the "Microsoft" way.
You save the token in you DB. No need for that. Token should be emailed to a user as a link and then clicked by user and this way the token will be passed to the controller where you reset the email.
You generate a new password for user. Don't do that - let users pick their own password. And you use Membership
for that - bad practice to mix Identity and MembershipProvider. MebershipProvider is very invasive and tries to take over when it can. Possibly it can cause issues later down the lifetime.
You email the password to a user. Very bad security practice. Email is not a secure channel. Let the user pick their new password on your web-page and don't ever email the passwords.
Highly recommended article by Troy Hunt about password resetting - a very worthy reading if you work with passwords.
Upvotes: 3