Я использую этот метод для сброса пароля
public ResetTokenResult DoPasswordResetTokenForChange(string userId, string token)
{
switch (UserManager.FindById(userId))
{
case null:
return ResetTokenResult.UnknownUserId;
case CatalystUser user when ! (user.PasswordInvalidatedByReset ?? false):
return ResetTokenResult.TokenIsExpired;
case CatalystUser user when ! ((user.PasswordResetTokenExpiration ?? DateTime.MinValue) > DateTime.UtcNow):
return ResetTokenResult.TokenIsExpired;
case CatalystUser user when UserManager.VerifyUserToken(user.Id, "ResetPassword", token):
user.PasswordResetTokenExpiration = DateTime.UtcNow.AddDays(-1); // 1-time use. Invalidate now.UserManager.Update(user);
return ResetTokenResult.Success;
default:
return ResetTokenResult.InvalidToken;
}
}
Контроллер, который я использую этим методом
[RequireHttpsWhenConfigured]
public async Task<ActionResult> Index(PasswordChangePage currentPage,
string userId, string token, string returnUrl = "")
{
var model = new PasswordChangePageViewModel(currentPage);
var isResetPasswordRequest = !string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(token);
if (!isResetPasswordRequest)
{
if (!RequestContext.IsCurrentUserAuthorized())
return Redirect(NavigationService.GetLoginLink());
model.PasswordChangeModel = new PasswordChangeViewModel {ReturnUrl = returnUrl};
model.ReturnUrl = returnUrl;
return View("Index", model);
}
if (RequestContext.IsCurrentUserAuthorized())
{
SignInManager.AuthenticationManager.SignOut();
return Redirect(Request.Url?.AbsoluteUri ?? "~/");
}
var loginLink = NavigationService.GetLoginLink();
var result = UserAccountService.DoPasswordResetTokenForChange(userId,Base64ForUrlDecode(token));
if ((result & ResetTokenResult.Failure) != ResetTokenResult.None)
{
model.ChangeCanProceed = false;
model.ErrorMessage = GetMessageForTokenResult(result);
model.LoginLink = loginLink;
}
else
{
model.PasswordChangeModel = new PasswordChangeViewModel { CurrentPassword = "null", IsResetPassword = true, UserId = userId, ResetPasswordToken = token };
model.ReturnUrl = loginLink;
}
return View("Index", model);
}
Когда пользователи хотят сбросить свой пароль, они получают электронное письмо со ссылкой токена, и все работает нормально. Как я знаю, токен ASPNET Identity по умолчанию горит после 1 клика по ссылке.
Мой вопрос заключается в том, каков наилучший способ реализации логики: ссылка на токен сгорает после 5 нажатий на ссылку, которая отправляется на электронную почту.