c# - 验证重置密码令牌在一种方法中失败,但在 ASP.NET 身份中的另一种方法中有效
问题描述
在实际重置密码之前,我们正在尝试使用UserManager
来生成并验证它。PasswordResetToken
第一种方法负责生成令牌,然后通过密码重置链接将其发送给用户。
令牌的生成工作正常,之后验证它时,VerifyUserTokenAsync
返回 true(行://var result = await this.userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, UserManager<User>.ResetPasswordTokenPurpose, token);
第二种方法是重置密码。我们没有使用,UserManager.ResetPassword
因为我们的用户没有所有必填字段。VerfiyUserTokenAsync
在此方法中调用时,false
即使提供的标记与第一个方法中的完全相同,if 也会返回。
我们无法理解为什么它在第一种方法中有效,但在第二种方法中失败了......
任何线索都将受到高度赞赏。
提前致谢
[HttpPost("generatepasswordresettoken")]
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> GeneratePasswordResetToken([FromBody] ResetPasswordTokenRequest resetPasswordTokenRequest)
{
var user = await this.userService.GetAsync(resetPasswordTokenRequest.Email);
var token = await this.userManager.GeneratePasswordResetTokenAsync(user);
//var result = await this.userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, UserManager<User>.ResetPasswordTokenPurpose, token);
return this.Ok(new GenerateResetPasswordTokeResponse {ResetPasswordToken = token, Email = resetPasswordTokenRequest.Email});
}
[HttpPut("resetpassword")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordRequest resetPasswordRequest)
{
var user = await this.userService.GetAsync(resetPasswordRequest.Email);
if (await this.userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, UserManager<User>.ResetPasswordTokenPurpose, resetPasswordRequest.ResetPasswordToken)) {
var resetPasswordDomainModel = this.resetPasswordMapper.Map(resetPasswordRequest);
if (await this.userService.ResetPasswordAsync(resetPasswordDomainModel)) {
return this.Ok();
}
}
return this.BadRequest("Couldn't reset password");
}
解决方案
每个 SecurityToken 应该只对一个操作有效,并且VerifyUserTokenAsync方法的这种行为是一个优势。否则,您需要编写一些代码来自己控制这种行为。在您的情况下,您可以生成新令牌,然后将其传递给ResetPasswordAsync方法。
[HttpPut("resetpassword")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordRequest resetPasswordRequest)
{
var user = await this.userService.GetAsync(resetPasswordRequest.Email);
if (await this.userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, UserManager<User>.ResetPasswordTokenPurpose, resetPasswordRequest.ResetPasswordToken))
{
var newtoken = userManager.GeneratePasswordResetTokenAsync(user);
resetPasswordRequest.ResetPasswordToken = newtoken;
var resetPasswordDomainModel = this.resetPasswordMapper.Map(resetPasswordRequest);
if (await this.userService.ResetPasswordAsync(resetPasswordDomainModel))
{
return this.Ok();
}
}
return this.BadRequest("Couldn't reset password");
}
推荐阅读
- objective-c - PRODUCT_BUNDLE_IDENTIFIER 如何用作应用程序错误的 NSErrorDomain?
- haskell - 如何在 Haskell 中评估这个通用抽象语法树?
- django - 在 Django Rest 中合并来自两个数据库的查询集
- javascript - 带有用户输入的 2 个目的地的 Google-map API 方向服务
- python - 如何用 Python 抓取 NBA 表格?
- javascript - JavaScript:如何使用较少重复的代码重构 if..else 语句?
- wordpress - 我们如何使用 wordpress REST API 创建帖子和页面?
- java - Java 无法找到正则表达式的匹配项
- apache-spark - 如何在 Cloudera 集群上分发 JDBC jar?
- sqlite - sqlite3:分离数据库产生数据库被锁定错误