【问题标题】:Forgot Password MVC 4忘记密码 MVC 4
【发布时间】:2014-05-05 12:45:55
【问题描述】:

在我的应用程序中,我试图让忘记密码才能工作。当用户输入他或她的用户名,发送他们和电子邮件时,我试图向用户发送一封电子邮件,他们点击该链接,并被带回网站并更改他们的密码。唯一的问题是我的 linq 查询错误,没有检查用户名是否存在于数据库中。这是通过忘记密码来工作的正确方法吗?

这是我的代码

控制器

    // GET: /Account/ForgotPassword
    [AllowAnonymous]
    public ActionResult ForgetPassword()
    {
        return View();
    }

    // Post: /Account/ForgotPassword
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult ForgetPassword(ForgetPasswordModel model, string UserName)
    {
        string emailAddress = (from i in db.UserProfiles
                                where i.UserName.Equals(model.Username)
                                select i.Email).Single();

        if (!string.IsNullOrEmpty(emailAddress))
        {
            string confirmationToken =
                WebSecurity.GeneratePasswordResetToken(model.Username);
            dynamic email = new Email("ChngPasswordEmail");
            email.To = emailAddress;
            email.UserName = model.Username;
            email.ConfirmationToken = confirmationToken;
            email.Send();

            return RedirectToAction("ResetPwStepTwo");
        }

        return RedirectToAction("InvalidUserName");
    }

型号

public class ForgetPasswordModel
{
    [Required]
    [Display(Name = "Username")]
    public string Username { get; set; }
}

查看

@model MyFestival.Models.UserProfile
@{
ViewBag.Title = "Forgot Password";
}

<hr />
<div class="form-group">
  <h3 class="panel-title">Did you forget your password?</h3>
</div>

@using (Html.BeginForm())


{
<div class="">
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true, null, new { @style = "color:red;" })
    <hr />
    <label>To reset your password, input your email address and press the Reset Password button.</label>
    <br/>
    <div class="form-group" >
        <div class="col-md-12" >
            <div class="input-group">
                <span class="input-group-addon" ><i class="glyphicon glyphicon-user" ></i ></span >
                @Html.TextBoxFor(m => m.UserName, new { @class = "form-control", @placeholder = "Username" })
            </div >
            @Html.ValidationMessageFor(m => m.UserName, null, new { @style = "color:red;" })
        </div>
    </div>
    <br/>
    <br/>
    <div class="form-group" >
        <div class="col-md-offset-2 col-md-10" >
            <input type="submit" class="btn btn-default"  value="Reset Password"/ >
            @Html.ActionLink("Back to Login", "Login", null, new { @class = "btn btn-info" })
        </div >
    </div>
</div>


}

【问题讨论】:

  • 目前发生了什么??
  • 然后创建一个查询来检查用户名是否存在?
  • 说到这里:string emailAddress = (from i in db.UserProfiles where i.UserName.Equals(model.Username) select i.Email).Single(); 例如,我使用我的用户名,它不会检查用户名是否存在于数据库中。并告诉我我的用户名在数据库中不存在,它确实存在。
  • 如果数据库中不存在电子邮件地址,它将RedirectToAction("InvalidUserName");,这是所需的。据我了解,这就是您想要的,对吧?
  • 您能否澄清一下您的解决方案到底出了什么问题?检查用户名是否存在的查询?如果是,您可以尝试分析您的 ORM 生成的 SQL 查询。此外,使用 Equals 的另一个重载可能很有用:i.UserName.Equals(model.Username, StringComparison.InvariantCultureIgnoreCase)

标签: c# asp.net-mvc linq


【解决方案1】:

我刚刚发现您将 ForgetPasswordModel modelstring username 作为控制器操作的参数,然后您使用模型的 Username 属性。我假设 Model Binder 只是初始化 stirng username 而不是 ForgegPasswordModel。您可以尝试删除stirng username - ForgetPassword 操作的第二个参数吗?

【讨论】:

  • 您能否确认model.Username 与网页上输入的值完全相同?下一步是验证 ORM 生成的 SQL 查询。您可以使用 SQL Server Management Studio 来执行此操作,只需转到工具 -> SQL Server Profiler,连接到您的数据库,开始分析会话,然后提交您的网页。您应该会在分析器窗口中看到一个 SQL 查询。
  • 我输入的用户名,是的,和model.Username一样。你告诉我的下一步,我不能这样做,因为我的 SQL Server Management Studio 中没有该选项
  • 我又想到了一件事。您可以使用 LINQPad (linqpad.net) 来调试您的查询,只需检查它是否可以在那里工作。顺便说一句,使用Single 有点破坏性 - 每次没有给定名称的用户时,它都会抛出异常。考虑改用SingleOrDefault
  • 对不起@takemyoxygen,犯了一个愚蠢的错误,我的用户名下的数据库中没有电子邮件地址!傻我。
  • 如果有人再次偶然发现,这里是详细的答案,写在我的博客上,一步一步的过程,看看qawithexperts.com/article/asp-net/…
【解决方案2】:

您可以创建自己的 GUID 并将其通过电子邮件发送给用户。 当用户单击电子邮件链接时,检查 Guid 并更新用户的新密码。

这里是示例代码

创建一个视图以输入忘记密码的电子邮件

@{
ViewBag.Title = "Forgot Password";
}

<h2>Forgot Password</h2>

 @using (Html.BeginForm())
 {
   <div class="form-horizontal">
  <hr />
   <div class="text-success">
      @ViewBag.Message
   </div>
    <div class="form-group">
    Please enter your registered email address below to receive an email containing a link, to reset your password.
   </div>
    <div class="form-group">
       <label class="control-label col-md-2">Email Address</label>
       @Html.TextBox("EmailID", "", new { @class = "form-control" })
  </div>
 <div class="form-group">
     <div class="col-md-offset-2 col-md-10">
         <input type="submit" value="Submit" class="btn btn-success" />
    </div>
</div>
  </div>
 }

然后在您的控制器中从用户那里获取电子邮件 ID,检查电子邮件是否存在并创建新的 GUID,将其保存在数据库中,向用户发送电子邮件。

    [HttpPost]
    public ActionResult ForgotPassword(string EmailID)
    {
        string resetCode = Guid.NewGuid().ToString();

        var verifyUrl = "/Account/ResetPassword/" + resetCode;

        var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyUrl);
       //get user details from database.
        using (var context = new LoginRegistrationInMVCEntities())
        {
            var getUser = (from s in context.RegisterUsers where s.Email == EmailID select s).FirstOrDefault();
            if (getUser != null)
            {
                getUser.ResetPasswordCode = resetCode;

                //This line I have added here to avoid confirm password not match issue , as we had added a confirm password property 

                context.Configuration.ValidateOnSaveEnabled = false;
                context.SaveChanges();

                var subject = "Password Reset Request";
                var body = "Hi " + getUser.FirstName + ", <br/> You recently requested to reset your password for your account. Click the link below to reset it. " +

                     " <br/><br/><a href='" + link + "'>" + link + "</a> <br/><br/>" +
                     "If you did not request a password reset, please ignore this email or reply to let us know.<br/><br/> Thank you";

                SendEmail(getUser.Email, body, subject);

                ViewBag.Message = "Reset password link has been sent to your email id.";
            }
            else
            {
                ViewBag.Message = "User doesn't exists.";
                return View();
            }
        }

        return View();
    }

    private void SendEmail(string emailAddress, string body, string subject)
    {
        using (MailMessage mm = new MailMessage("youremail@gmail.com", emailAddress))
        {
            mm.Subject = subject;
            mm.Body = body;

            mm.IsBodyHtml = true;
            SmtpClient smtp = new SmtpClient();
            smtp.Host = "smtp.gmail.com";
            smtp.EnableSsl = true;
            NetworkCredential NetworkCred = new NetworkCredential("youremail@gmail.com", "YourPassword");
            smtp.UseDefaultCredentials = true;
            smtp.Credentials = NetworkCred;
            smtp.Port = 587;
            smtp.Send(mm);

        }
    }

现在,当用户点击电子邮件并输入新密码时,检查 Guid 与我们保存在数据库中的内容,如果 guid 匹配则更新密码。

查看更多信息:

Forgot password functionality in ASP.NET MVC (Reset password by Email)

【讨论】:

    猜你喜欢
    • 2013-05-13
    • 2012-07-25
    • 2017-04-26
    • 2012-12-20
    • 2013-05-17
    • 2011-08-26
    • 2015-12-31
    • 1970-01-01
    • 2016-02-14
    相关资源
    最近更新 更多