2

I am trying to add the reset password functionality in my mvc web application.

When I enter my e-mail address and submit the form I receive the e-mail that contains the token etc, then when I click on the link I got redirected to the reset password page, there I enter my e-mail and the new password, then when I hit reset button I got the following error from the resetPassword action:

"invalid token".

 [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) { if (!ModelState.IsValid) { return View(model); } var user = await UserManager.FindByNameAsync(model.Email); if (user == null) { // Don't reveal that the user does not exist return RedirectToAction("ResetPasswordConfirmation", "Account"); } var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); if (result.Succeeded) { return RedirectToAction("ResetPasswordConfirmation", "Account"); } AddErrors(result); return View(); } 

And my ForgotPassword Method:

 [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model) { if (ModelState.IsValid) { var user = await UserManager.FindByNameAsync(model.Email); if (user == null) { // Don't reveal that the user does not exist or is not confirmed return View("ForgotPasswordConfirmation"); } string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); var emailTemplateQuery = await _emailTemplateService.Query(x => x.Slug.ToLower() == "forgotpassword").SelectAsync(); var emailTemplate = emailTemplateQuery.Single(); dynamic email = new Postal.Email("Email"); email.To = user.Email; email.From = CacheHelper.Settings.EmailAddress; email.Subject = emailTemplate.Subject; email.Body = emailTemplate.Body; email.CallbackUrl = callbackUrl; EmailHelper.SendEmail(email); return RedirectToAction("ForgotPasswordConfirmation", "Account"); } 

ForgotPassword.cshtml file:

 <div class="panel-body"> @using (Html.BeginForm("ForgotPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>[[[Enter your email.]]]</h4> <hr /> @Html.ValidationSummary("", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" class="btn btn-default" value="[[[Email Link]]]" /> </div> </div> } </div> 

ForgotPasswordConfirmation.cshtml file:

 <div class="panel-body"> <div> <p> [[[Please check your email to reset your password.]]] </p> </div> </div> 

ResetPasswordViewModel:

public class ResetPasswordViewModel { [Required] [EmailAddress] [Display(Name = "[[[Email]]]")] public string Email { get; set; } [Required] [StringLength(100, ErrorMessage = "[[[The {0} must be at least {2} characters long.]]]", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "[[[Password]]]")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "[[[Confirm password]]]")] [Compare("Password", ErrorMessage = "[[[The password and confirmation password do not match.]]]")] public string ConfirmPassword { get; set; } public string Code { get; set; } } 
11
  • Can you add your view model + full error log ? Commented Mar 21, 2017 at 8:43
  • is it asp.net MVC 5? Commented Mar 21, 2017 at 9:11
  • Yes, it is Mvc 5 Commented Mar 21, 2017 at 9:15
  • you should add code of ForgotPasswordConfirmation action and ForgotPassword view and model also. Commented Mar 21, 2017 at 9:19
  • 1
    Hi Antonie, i added ResetPasswordViewModel. But i don't know full error log. How do i find ? Commented Mar 21, 2017 at 14:33

1 Answer 1

1

Thank you for your help.I have added the following code and i solved the problem.

ResetPassword Method:

string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); var result = await UserManager.ResetPasswordAsync(user.Id, code, model.Password); 
Sign up to request clarification or add additional context in comments.

3 Comments

I think this wont solve your issue, you're generating a token just before reseting the password and you're not using the one you sent by mail. It works yes, but it's a security issue in my opinion.
Yes, you are right. But, if i don't have the code, i can't enter the reset password page. Even so, i know it's not safe. Else, how do I solve it?
I actually just ended up using this solution too... bumped my head for days and have no other option...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.