Suggested Videos
Part 113 - ASP.NET Core email confirmation | Text | Slides
Part 114 - External login email confirmation in asp.net core | Text | Slides
Part 115 - Forgot password in asp.net core | Text | Slides
In this video we will discuss, how to implement password reset functionality in asp.net core. This is continuation to our previous video Part 115. Please watch Part 115 from asp.net core tutorial before proceeding.
To be able to reset the user password we need the following
The user provides the new password and confirmation password. Email and reset token are in the password reset link.
Reset Password View Model
Reset Password View
We are using 2 hidden input fields to store email address and password reset token as we need them on postback.
Reset Password Action Methods
Include the following HTTP GET and POST RestPassword() actions in the AccountController. The code in these 2 actions is commented and self-explanatory.
Reset Password Confirmation View
Part 113 - ASP.NET Core email confirmation | Text | Slides
Part 114 - External login email confirmation in asp.net core | Text | Slides
Part 115 - Forgot password in asp.net core | Text | Slides
In this video we will discuss, how to implement password reset functionality in asp.net core. This is continuation to our previous video Part 115. Please watch Part 115 from asp.net core tutorial before proceeding.
To be able to reset the user password we need the following
- Email,
- Password reset token,
- New Password and
- Confirm Password
The user provides the new password and confirmation password. Email and reset token are in the password reset link.
Reset Password View Model
namespace EmployeeManagement.ViewModels
{
public class ResetPasswordViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password",
ErrorMessage = "Password and Confirm Password must match")]
public string ConfirmPassword { get; set; }
public string Token { get; set; }
}
}
{
public class ResetPasswordViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password",
ErrorMessage = "Password and Confirm Password must match")]
public string ConfirmPassword { get; set; }
public string Token { get; set; }
}
}
Reset Password View
We are using 2 hidden input fields to store email address and password reset token as we need them on postback.
@model
ResetPasswordViewModel
<h2>Reset Password</h2>
<hr />
<div class="row">
<div class="col-md-12">
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<input asp-for="Token" type="hidden" />
<input asp-for="Email" type="hidden" />
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword"></label>
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn
btn-primary">Reset</button>
</form>
</div>
</div>
Reset Password Action Methods
Include the following HTTP GET and POST RestPassword() actions in the AccountController. The code in these 2 actions is commented and self-explanatory.
[HttpGet]
[AllowAnonymous]
public IActionResult ResetPassword(string token, string email)
{
//
If password reset token or email is null, most likely the
//
user tried to tamper the password reset link
if (token == null || email == null)
{
ModelState.AddModelError("", "Invalid password reset token");
}
return View();
}
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult>
ResetPassword(ResetPasswordViewModel model)
{
if (ModelState.IsValid)
{
//
Find the user by email
var user = await
userManager.FindByEmailAsync(model.Email);
if (user != null)
{
// reset the user password
var result = await userManager.ResetPasswordAsync(user,
model.Token, model.Password);
if (result.Succeeded)
{
return View("ResetPasswordConfirmation");
}
// Display validation errors. For example,
password reset token already
// used to change the password or password
complexity rules not met
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(model);
}
//
To avoid account enumeration and brute force attacks, don't
//
reveal that the user does not exist
return View("ResetPasswordConfirmation");
}
//
Display validation errors if model state is not valid
return View(model);
}
Reset Password Confirmation View
<h4>
Your password is reset. Please click <a asp-action="Login">here to login</a>
</h4>
why do I always get an "invalid token" error message, even though I haven't changed the token at all?
ReplyDeleteBecause the URL get encoded automatically by the browser , so it is different than the one of the user
ReplyDeleteUse this to create the resetPasswordLink:
string token = HttpUtility.UrlEncode(await userManager.GeneratePasswordResetTokenAsync(user));
and use this before uncoded token in the ResetPasswordAsync method :
var decoded_token = HttpUtility.UrlDecode(token);