As we know when we create an ASP.NET Core
app with Individual User Accounts
mode, the Visual Studio template generates some account related code and Views etc. Question: When implementing Forgot Password functionality, is Email Confirmation a requirement in ASP.NET Core?
For example in the following ForgotPassword(...)
Post action generated by Visual Studio, if _userManager.IsEmailConfirmedAsync(user)
is not true the ResetPassword
link is not generated and email is not sent to the user. I then tried the code by removing _userManager.IsEmailConfirmedAsync(user)))
from the code below but then, although, the ResetPassword
link gets generated and an email with that link is successfully sent but I when I click on the link in the email and correctly fill in the Reset Password
form and submit it, I get the validation error as: Invalid Token
. In our case there are only four users all of whom were create using Register.cshtml view but we did not use Email confirmation functionality at the time of creating these users. NOTE: We're using ASP.NET Core 1.1.1
with VS2017
. The code is on the same machine (windows 10) where the email is checked and the generated Reset Password
link is clicked. The ASPNETUsers table has SecurityStamp value for all four users. So there should probably no SecurityStamp or machineKey related issue on Invalid Token
error.
AccountController
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
// Send an email with this link
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = Url.Action(nameof(ResetPassword), "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
await _emailSender.SendEmailAsync(model.Email, "Reset Password",
$"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
return View("ForgotPasswordConfirmation");
}
// If we got this far, something failed, redisplay form
return View(model);
}