当我尝试通过电子邮件单击重置密码链接来重置密码时,出现无效令牌错误。
我一直在寻找问题所在,并看到了很多解决方案,例如编码和解码、替换“+”等,但它们都不适合我的环境。
我的“忘记密码”代码如下所示:
public IActionResult ForgetPassword()
{
return View();
}
[HttpPost]
public async Task<IActionResult> ForgetPassword(ForgetPasswordViewModel forgetPasswordView)
{
var hasUser = await _userManager.FindByEmailAsync(forgetPasswordView.Email);
if (hasUser == null)
{
ModelState.AddModelError(string.Empty, "Bu email adresine sahip bir kullanıcı bulunamamıştır.");
return View();
}
string passwordResetToken = await _userManager.GeneratePasswordResetTokenAsync(hasUser);
var passwordResetLink=Url.Action("ResetPassword", "Home", new { userId = hasUser.Id, Token = passwordResetToken }, HttpContext.Request.Scheme);
await _emailService.SendResetPasswordEmail(passwordResetLink, hasUser.Email);
TempData["SuccessMessages"] = "Şifre yenileme linki email adresinize gönderilmiştir.";
return RedirectToAction(nameof(ForgetPassword));
}
我的重置密码代码块是这样的:
public IActionResult ResetPassword(string userId,string token)
{
TempData["userId"] = userId;
TempData["token"] = token;
return View();
}
[HttpPost]
public async Task<IActionResult> ResetPassword(ResetPasswordViewModel request)
{
var userId = TempData["userId"];
var token = TempData["token"];
if (userId == null || token == null)
{
throw new Exception("Bir hata meydana geldi.");
}
var hasUser = await _userManager.FindByIdAsync(userId.ToString()!);
if (hasUser == null)
{
ModelState.AddModelError(String.Empty, "Kullanıcı bulunamamıştır.");
}
IdentityResult result = await _userManager.ResetPasswordAsync(hasUser, (string)token, request.Password);
if (result.Succeeded)
{
TempData["SuccessMessages"] = "Şifreniz başarı ile değiştirilmiştir.";
}
else
{
ModelState.AddModelErrorList(result.Errors.Select(x => x.Description).ToList());
}
return View();
}
我检查了所有 Stackoverflow 相关主题,并尝试了这些主题中提供的许多解决方案,但我仍然无法解决该问题。
我在尝试重置我的设备时收到无效令牌错误 单击通过电子邮件重置密码链接即可获得密码。
我一直在寻找问题所在并看到了很多解决方案 例如编码和解码,替换“+”等,但它们都不起作用 我的背景
嗯,根据您的描述和情况,您可能会收到错误,因为在发送重置密码链接时缺乏正确的编码。
我看不到您如何尝试发送重置密码链接。
Asp.net core Identity 有自己的机制来处理,不要自己手动处理。始终建议使用框架提供的方式,因为它有自己经过测试的方式。
为了解决实际问题,您应该检查您是否使用了正确的
WebEncoders.Base64UrlEncode
,除此之外,您的令牌无法相应地识别用户凭据。
最重要的是,在电子邮件链接中生成和存储令牌时使用
WebEncoders.Base64UrlEncode
,并在 WebEncoders.Base64UrlDecode
操作中使用 ResetPassword
解码令牌。避免手动编码/解码 让框架处理它以保持一致性。
此外,检查其他配置,例如令牌过期时间或 确保您正在等待异步调用,例如
_userManager.GeneratePasswordResetTokenAsync
和 _emailService.SendResetPasswordEmail
。
因此,为了重置您的密码,您应该相应地执行3个步骤,
首先获取需要重置密码的用户,然后使用
GeneratePasswordResetTokenAsync
生成密码生成令牌并传递给用户init。最后,调用 ResetPasswordAsync
并传递上述参数,如下所示:
var resetPassResult = await UserManager.ResetPasswordAsync(user, token, "YourNewPass@OneSpecial!andNumber28");
您应该按以下方式实施:
重置链接:
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
重置密码:
var user = await _userManager.FindByEmailAsync(resetPasswordModel.Email);
if (user == null)
RedirectToAction(nameof(ResetPasswordConfirmation));
var resetPassResult = await _userManager.ResetPasswordAsync(user, resetPasswordModel.Token, resetPasswordModel.Password);
if(!resetPassResult.Succeeded)
{
foreach (var error in resetPassResult.Errors)
{
ModelState.TryAddModelError(error.Code, error.Description);
}
return View();
}
注意: 在发送令牌生成链接时,请再次仔细检查您是否已正确对令牌进行结束编码和解码。如果您需要其他帮助,请参阅此官方文档。