如何使用 ASP.NET MVC 5.0 的标识实现密码重置 ASP.NET
本文关键字:ASP NET 实现 密码 标识 何使用 MVC | 更新日期: 2023-09-27 18:32:48
Microsoft提出了一个名为 ASP.NET Identity的新会员系统(也是MVC 5 ASP.NET 中的默认设置)。我找到了示例项目,但这没有实现密码重置。
关于密码重置主题刚刚找到这篇文章:使用一个 ASP.NET 身份实现用户确认和密码重置 - 痛苦或快乐,对我没有帮助,因为不要使用内置的密码恢复。
当我查看选项时,因为我认为我们需要生成一个重置令牌,我将将其发送给用户。然后,用户可以使用令牌设置新密码,覆盖旧密码。
我找到了IdentityManager.Passwords.GenerateResetPasswordToken
/IdentityManager.Passwords.GenerateResetPasswordTokenAsync(string tokenId, string userName, validUntilUtc)
,但我无法弄清楚tokenId
参数可能意味着什么。
如何在 MVC 5.0 ASP.NET 中实现密码重置?
我明白了:tokenid是一个自由选择的身份,它标识了一个密码选项。例如
1.看起来像密码恢复过程,步骤1(它基于:https://stackoverflow.com/a/698879/208922)
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPassword(
ResetPasswordViewModel rpvm)
{
string message = null;
//the token is valid for one day
var until = DateTime.Now.AddDays(1);
//We find the user, as the token can not generate the e-mail address,
//but the name should be.
var db = new Context();
var user = db.Users.SingleOrDefault(x=>x.Email == rpvm.Email);
var token = new StringBuilder();
//Prepare a 10-character random text
using (RNGCryptoServiceProvider
rngCsp = new RNGCryptoServiceProvider())
{
var data = new byte[4];
for (int i = 0; i < 10; i++)
{
//filled with an array of random numbers
rngCsp.GetBytes(data);
//this is converted into a character from A to Z
var randomchar = Convert.ToChar(
//produce a random number
//between 0 and 25
BitConverter.ToUInt32(data, 0) % 26
//Convert.ToInt32('A')==65
+ 65
);
token.Append(randomchar);
}
}
//This will be the password change identifier
//that the user will be sent out
var tokenid = token.ToString();
if (null!=user)
{
//Generating a token
var result = await IdentityManager
.Passwords
.GenerateResetPasswordTokenAsync(
tokenid,
user.UserName,
until
);
if (result.Success)
{
//send the email
...
}
}
message =
"We have sent a password reset request if the email is verified.";
return RedirectToAction(
MVC.Account.ResetPasswordWithToken(
token: string.Empty,
message: message
)
);
}
2 然后当用户输入令牌和新密码时:
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPasswordWithToken(
ResetPasswordWithTokenViewModel
rpwtvm
)
{
if (ModelState.IsValid)
{
string message = null;
//reset the password
var result = await IdentityManager.Passwords.ResetPasswordAsync(
rpwtvm.Token,
rpwtvm.Password
);
if (result.Success)
{
message = "the password has been reset.";
return RedirectToAction(
MVC.Account.ResetPasswordCompleted(message: message)
);
}
else
{
AddErrors(result);
}
}
return View(MVC.Account.ResetPasswordWithToken(rpwtvm));
}
在github上采样项目的骨架建议,如果有人需要,可以进行测试。电子邮件发送尚未写入,可能很快就会添加。
似乎很麻烦...以上有什么好处:
- 用户点击了"恢复帐号"链接
- 这会在电子邮件中发送一个 64 字节的 DATETIME 刻度值编码字符串(称为 psuedo-hash)
- 单击电子邮件中返回的控制器/操作路由的链接
- 将电子邮件及其源服务器与伪哈希匹配,解密伪哈希,验证自发送以来的时间,以及
- 为用户提供设置新密码的视图
- 使用有效密码,代码将删除旧用户密码并分配新密码。
- 完成后,无论成功与否,删除伪哈希。
使用此流程,您任何时候都不会将密码发送到您的域中。
请,任何人,向我证明这是多么不安全。