MVC4接收密码重置令牌的模式
本文关键字:令牌 模式 密码 MVC4 | 更新日期: 2023-09-27 18:27:15
正在尝试设置密码重置功能。这将适用于尚未也无法登录到系统的用户。我想我已经接近了,但感觉不对:
我有一个ResetPassword方法/视图。。。它只是询问用户的电子邮件地址,不向用户确认帐户,但如果存在帐户,则使用link+令牌发送电子邮件。这一切都很好。
下一部分是我的问题所在。。。。我用这种方法(通过点击用户的电子邮件链接)收到密码令牌:
[HttpGet]
public ActionResult ReceiveResetToken(string token)
{
try
{
if (!String.IsNullOrEmpty(token))
{
var username = (from u in db.Users
where u.Userid == WebSecurity.GetUserIdFromPasswordResetToken(token)
select u.Email).ToString();
if (!String.IsNullOrEmpty(username))
{
WebSecurity.ConfirmAccount(token);
}
}
RedirectToAction("Index", "Home");
}
catch (Exception)
{
throw;
}
}
我错过了一些显而易见的东西。这个方法并不完整,因为我一直在重新思考……获取用户名,确认帐户,在不知道密码的情况下以某种方式登录,重定向到更改密码页面?感觉不对。
所以我想,也许可以把带有ViewBag的隐藏用户名传给更改对话框。。。感觉也不对劲。我想要一个更优雅的方法,接收令牌,向用户名询问新密码,更新数据库并登录。接收密码重置令牌的模式是什么?
编辑-------
因此,当我继续寻找答案时,我发现了这个小宝石。显然,有一个WebSecurity.ResetPassword方法可以接受令牌和新密码。这感觉是正确的路径,无需担心登录,只需更改并重定向到登录即可。。。我将完成代码并发布解决方案,因为这似乎是SO上一个流行且经常没有答案的问题。
如果有人能确认我走在正确的道路上,或者发表任何关于为模式添加优雅的想法,那将是很酷的
这是一条正确的道路!
对我来说,
用户给了他电子邮件,我给他发了一个生成GUID
的令牌,我有passwordResetTokenDate
,当用户要求重置时,他会记下日期。(代币48小时有效)
在电子邮件中,有一个带有令牌的链接,我给他一个令牌,如果他点击时出现问题,他可以复制粘贴在文本框中的令牌,或者重新点击链接
当他点击链接时,我检查令牌和日期以及passwordResetTokenDate
,如果一切正常,有两个文本框,用户输入2倍于他的新密码。
当他保存密码时,我把他记录了下来。
WebSecurity.ResetPassword
做好工作!
这里有一个例子:(我有一个带有自定义提供者的自定义网络安全)
[AllowAnonymous]
public ActionResult ForgotMyPassword(string confirmation, string username)
{
username = HttpUtility.UrlDecode(username);
ViewBag.Succeed = false;
SetPasswordViewModel Fmp = new SetPasswordViewModel(username,confirmation);
return View(Fmp);
}
//
// POST: /Account/ForgotMyPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ForgotMyPassword(SetPasswordViewModel model)
{
ViewBag.Succeed = false;
if (ModelState.isValid)
{
ViewBag.Succeed = WebSecurity.ResetPassword(model.UserName, model.PasswordResetToken, model.Password.NewPassword);
}
if (!ViewBag.Succeed)
{
ModelState.AddModelError("","something"); //something
}
return View(model);
}
这就是它应该如何工作(在ASP安全工具包中实现)
- 用户点击忘记密码链接(例如打开/帐户/忘记)
- 在这个页面上,您询问用户的用户名(可能是他的电子邮件)
- 您检查该用户是否存在。如果是,则生成一个重置令牌,将其保存在该用户名的数据库中,并向该用户发送一封带有链接的电子邮件(http://yourdomain.com/account/confirm/[tokenHere])
- 您向用户显示一条类似"如果您有一个使用此用户名的帐户,您将很快收到一封包含重置密码说明的电子邮件"的消息。但您没有在该页面上登录用户,因为您只是要求他提供用户名
- 用户收到电子邮件,点击链接,重置密码页面打开(/account/confirm/[tokenHere])
- 在此页面上,用户需要填写密码和确认密码字段。一旦完成,您将重定向用户到登录页面(您可能会争辩说,一旦用户重置密码,您就可以直接登录;但重定向到登录似乎是大多数网站遵循的标准做法。)
回答我自己的问题,以防对任何人都有帮助。
- 提供一个表格,要求提供电子邮件地址以发送密码重置链接
- 使用
WebSecurity.GeneratePasswordResetToken(email, 1440)
生成令牌 - 通过指向令牌接收方法的链接向用户发送电子邮件
- 编写一个HttpGet方法来接收令牌并显示newPassword表单
- 表单将令牌和新密码模型发布到使用WebSecurity.ResetPassword(令牌,newPassword)的方法
- 重定向到登录
还没有全部写出来,但我认为这是正确的方法