1

试图获得密码重置功能。这适用于尚未也无法登录系统的用户。我想我很接近,但感觉不对:

我有一个 ResetPassword 方法/视图...它只是询问用户的电子邮件地址,不向用户确认帐户,但如果存在,发送带有链接+令牌的电子邮件。这一切都很好。

下一部分是我的问题所在......我使用这种方法收到密码令牌(通过单击用户的电子邮件链接):

[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 方法。这感觉是正确的路径,无需担心登录,只需更改它并重定向到登录...我将完成代码并发布解决方案,因为这似乎是一个流行且经常未回答的问题。

如果有人能确认我走在正确的道路上,或者发表任何关于为模式添加优雅的想法,那就太酷了

4

3 回答 3

2

这是一条正确的道路!

为了我,

用户给他的电子邮件,我向他发送一个生成的令牌,当用户要求重置时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);
    }
于 2013-08-10T19:32:43.220 回答
1

这就是它应该如何工作(在ASP Security Kit中实现)

  1. 用户点击忘记密码链接(例如打开 /account/forgot)
  2. 在此页面上,您向用户询问他的用户名(可能是他的电子邮件)。
  3. 您检查该用户是否存在。如果是,您生成一个重置令牌,将其保存在该用户名的数据库中,并向该用户发送一封带有链接的电子邮件 (http://yourdomain.com/account/confirm/[tokenHere])
  4. 您向用户显示一条消息,例如“如果您有使用此用户名的帐户,您将收到一封电子邮件,其中包含很快重置密码的说明。” 但是您没有在此页面上登录用户,因为您只是向他询问了他的用户名!
  5. 用户收到邮件,点击链接,重置密码页面打开(/account/confirm/[tokenHere])
  6. 在此页面上,用户需要填写密码并确认密码字段。完成后,您会将用户重定向到登录页面(您可能会争辩说,一旦用户重置密码,您就可以直接登录用户;但重定向到登录似乎是大多数网站遵循的标准做法。)
于 2013-08-10T19:25:33.283 回答
1

回答我自己的问题,以防它帮助任何人。

  1. 提供要求电子邮件地址发送密码重置链接的表格
  2. 用于WebSecurity.GeneratePasswordResetToken(email, 1440)生成令牌
  3. 使用指向令牌接收方法的链接向用户发送电子邮件
  4. 编写一个HttpGet方法接收token并显示newPassword形式
  5. 表单将令牌和新密码模型发布到使用 WebSecurity.ResetPassword(token, newPassword) 的方法
  6. 重定向到登录

还没有写完,但我认为这是正确的方法

于 2013-08-10T19:26:35.973 回答