请注意,GeneratePasswordResetTokenAsync、GenerateChangeEmailTokenAsync 和类似方法在后台使用 GenerateUserTokenAsync(user, provider, purpose) 并指定了提供者和目的。
我们可以使用GenerateUserTokenAsync(user, provider, purpose) 以我们想要的方式生成令牌。所以这将是我的终点:
[HttpPost("sendResetPasswordToken")]
[ServiceFilter(typeof(ModelValidationFilter))]
public async Task<IActionResult> SendChangePasswordToken([FromBody] SendChangePasswordTokenDto dto)
{
var user = await _userManager.FindByNameAsync(dto.UserName);
if (user is null)
return UnprocessableEntity("something went wrong, contact support to resolve the problem");
var token = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultPhoneProvider, "ResetPasswordPurpose");
_SMSManager.SendResetPasswordToken(token, user.PhoneNumber);
return NoContent();
}
我们将提供程序参数设置为TokenOptions.DefaultPhoneProvider,这是一个默认的电话令牌提供程序,并将目的参数设置为"ResetPasswordPurpose",这是一个指示令牌用途的字符串。
为了验证这个令牌,我们使用VerifyUserTokenAsync(user, provider, purpose, token) 并提供适当的参数。所以这是我的 ResetPassword 端点:
[HttpPost("resetPassword")]
[ServiceFilter(typeof(ModelValidationFilter))]
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto dto)
{
var user = await _userManager.FindByNameAsync(dto.SSN);
if(user is null)
return UnprocessableEntity("invalid user token");//actually user not found
var tokenVerified = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultPhoneProvider, "ResetPasswordPurpose", dto.Token);
if (!tokenVerified)
return UnprocessableEntity("invalid user token");
var token = await _userManager.GeneratePasswordResetTokenAsync(user);//new token for reseting password
var result = await _userManager.ResetPasswordAsync(user, token, dto.NewPassword);
if (!result.Succeeded)
return UnprocessableEntity("weak password");
return NoContent();
}