要重置密码,我们需要知道UserId并将其传递给UserManager.ResetPasswordAsync方法。在Identity 1.0中,可以从UserManager.PasswordResetTokens.Validate方法获取UserId((UserManager.PasswordResetTokens.Validate(token))。UserId)。现在它已经消失,所有现有的例子告诉我,我需要询问用户的用户名或电子邮件。这不是用户友好的,如果令牌有效,我不希望我的用户再次输入用户名。
这已经是ASP.NET身份中已经建立的传统 - 以前工作的东西在新版本中被破坏了。当然我可以使用嵌入式UserId创建自己的组合令牌,但为什么我需要做额外的工作呢?新版本应该改进,而不是让它们变得更糟。
答案 0 :(得分:1)
Asp.Net Identity 2.x没有提供一种通过从GeneratePasswordResetTokenAsync方法创建的令牌来查找用户的方法。
您有两个选择:
1)在要发送给用户的URL上添加用户ID。例如:
var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
var callbackUrl = $"/reset-password/?user={WebUtility.UrlEncode(applicationUser.Id)}&code={WebUtility.UrlEncode(token)}";
这种方法更加用户友好。但是我知道有人说这是一个安全问题,因为知道链接的任何人都可以重设用户密码。
2)和您一样,在“重置密码”页面上询问用户名。例如:
public async Task<YourResultModel> ResetPassword(ResetPasswordViewModel vm)
{
// Your password validations...
var user = await _userManager.FindByNameAsync(vm.UserName);
// could be FindByEmailAsync if your app uses the user e-mail to login.
IdentityResult result = await _userManager.ResetPasswordAsync(user, vm.Token, vm.NewPassword);
return YourResultModelFromIdentityResult(result);
}
在这两种方法之间进行选择之前,您需要考虑自己的特定情况。例如:如果您的应用使用用户电子邮件作为用户名,并且要拦截“拦截器”需要访问用户电子邮件的令牌,则从重置密码链接中删除用户ID不会提高您应用的安全性。因为知道链接的人已经知道用户的电子邮件。