Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>FORGOT PASSWORD FUNCTIONALITY</p> <p>The other day I was trying to create a “forgot password functionality” in asp.net MVC 4. I googled in and out but couldn't get the best solution. I have finally found the way out. 15 simple steps</p> <p>Part 1 Sending Password Reset Information via Email</p> <p>Step 1 • Create Mvc 4 c# Internet application template :) (Account and home controllers will automatically be generated) • Build and run your project. Register and login. (Simple membership tables will be generated)</p> <pre><code> Everything working fine? </code></pre> <p>Step 2 • Oops!! They don’t ask our email id while registration! In order to send password token to users we need their email id!! So let’s make a few changes in database go to server explorer! ( If u can’t find it u can press Ctrl + alt + S ) • Expand "data connections" and u will see a couple of tables. Open User Profile table. Add the following columns:</p> <ol> <li>EmailId nvarchar(max) 2.Details nvarchar(max)</li> </ol> <p>Step 3 • Now go to Solution Explorer...Models ... Account model ... Register model • Add these two properties for Email Id and Details</p> <pre><code>//new properties [Required] [Display(Name="Email ID")] public string EmailId { get; set; } [Required] [Display(Name = "About Yourself")] public string Details { get; set; } </code></pre> <p>Step 4 • Now go to Solution Explorer…Views ... Account Views ... Register.cshtml view • Add these two properties for allowing users to enter email id and other details.</p> <p><li> @Html.LabelFor(m => m.EmailId) @Html.TextBoxFor(m => m.EmailId) </li> <li> @Html.LabelFor(m => m.Details) @Html.TextBoxFor(m => m.Details) </li></p> <p>Step 5 • Now go to Solution Explorer…Controllers ... Account Controller ... Post version of Register controller action method • Add these properties for allowing users to enter email id and other details.The changes are highlighted.</p> <pre><code>[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult Register(RegisterModel model) { if (ModelState.IsValid) { // Attempt to register the user try { WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { EmailId = model.EmailId, Details = model.Details}); WebSecurity.Login(model.UserName, model.Password); return RedirectToAction("Index", "Home"); } catch (MembershipCreateUserException e) { ModelState.AddModelError("", ErrorCodeToString(e.StatusCode)); } } // If we got this far, something failed, redisplay form return View(model); } </code></pre> <p>Why don’t we again build and run our project? Register and fill in the details .Now you will be asked to specify email address also .Add these properties for allowing users to enter email id and other details.</p> <p>Go to server explorer and right click on User Profile table and Select “Show Table Data” U can view the details you entered for verification.</p> <p>Step 6 • Now lets implement the password reset functionality  Go to account controller and create the following controller action method (GET )</p> <pre><code>[AllowAnonymous] public ActionResult ForgotPassword() { return View(); } • (POST) [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ForgotPassword(string UserName) { //check user existance var user = Membership.GetUser(UserName); if (user == null) { TempData["Message"] = "User Not exist."; } else { //generate password token var token = WebSecurity.GeneratePasswordResetToken(UserName); //create url with above token var resetLink = "&lt;a href='" + Url.Action("ResetPassword", "Account", new { un = UserName, rt = token }, "http") + "'&gt;Reset Password&lt;/a&gt;"; //get user emailid UsersContext db = new UsersContext(); var emailid = (from i in db.UserProfiles where i.UserName == UserName select i.EmailId).FirstOrDefault(); //send mail string subject = "Password Reset Token"; string body = "&lt;b&gt;Please find the Password Reset Token&lt;/b&gt;&lt;br/&gt;" + resetLink; //edit it try { SendEMail(emailid, subject, body); TempData["Message"] = "Mail Sent."; } catch (Exception ex) { TempData["Message"] = "Error occured while sending email." + ex.Message; } //only for testing TempData["Message"] = resetLink; } return View(); } </code></pre> <p>• The GET controller action just returns the view. • The POST controller action : Receives the username Verifies its existence Generates Password reset token Builds URL to be emailed.</p> <p>Step 7 • Right click on the forgot password action method and add view  The code for the view page will be as below </p> <pre><code>@{ ViewBag.Title = "Forgot Password"; } &lt;h2&gt;Forgot Password&lt;/h2&gt; @using (Html.BeginForm()) { @Html.AntiForgeryToken() &lt;fieldset&gt; &lt;legend&gt;Forgot Password Form&lt;/legend&gt; &lt;ol&gt; &lt;li&gt; @Html.Label("User Name", new { @for = "UserName" }) @Html.TextBox("UserName") &lt;span style="color:red;"&gt;@TempData["Message"]&lt;/span&gt; &lt;/li&gt; &lt;/ol&gt; &lt;input type="submit" value="Recover" /&gt; &lt;/fieldset&gt; } </code></pre> <p>• The view page will display a textbox where in user can enter the user name.</p> <p>Step 8 • Now go to Solution Explorer...Models ... Account model … User Profile View Model. Changes have been highlighted</p> <pre><code>[Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } //new properties public string EmailId { get; set; } public string Details { get; set; } } </code></pre> <p>Step 9 • Now go to Solution Explorer...Views ... Account … Login View. Now we can see an option to recover his password in case he has forgotten it.</p> <pre><code>&lt;ul&gt; &lt;li&gt; @Html.ActionLink("Register", "Register") if you don't have an account. &lt;/li&gt; &lt;li&gt; @Html.ActionLink("Forgot Password", "ForgotPassword") if you want to recover your password. &lt;/li&gt; &lt;/ul&gt; </code></pre> <p>Part 2 Receiving Password Reset Information from URL</p> <p>Step 1 • Go to Solution Explorer...Controller ... Account Controller … Create new Reset Password Action Method • This method is accepting ‘un’ (which is username) and ‘rt’ (which is password reset token) from the URL.</p> <pre><code>[AllowAnonymous] public ActionResult ResetPassword(string un, string rt) { UsersContext db = new UsersContext(); //TODO: Check the un and rt matching and then perform following //get userid of received username var userid = (from i in db.UserProfiles where i.UserName == un select i.UserId).FirstOrDefault(); //check userid and token matches bool any = (from j in db.webpages_Memberships where (j.UserId == userid) &amp;&amp; (j.PasswordVerificationToken == rt) //&amp;&amp; (j.PasswordVerificationTokenExpirationDate &lt; DateTime.Now) select j).Any(); if (any == true) { //generate random password string newpassword = GenerateRandomPassword(6); //reset password bool response = WebSecurity.ResetPassword(rt, newpassword); if (response == true) { //get user emailid to send password var emailid = (from i in db.UserProfiles where i.UserName == un select i.EmailId).FirstOrDefault(); //send email string subject = "New Password"; string body = "&lt;b&gt;Please find the New Password&lt;/b&gt;&lt;br/&gt;" + newpassword; //edit it try { SendEMail(emailid, subject, body); TempData["Message"] = "Mail Sent."; } catch (Exception ex) { TempData["Message"] = "Error occured while sending email." + ex.Message; } //display message TempData["Message"] = "Success! Check email we sent. Your New Password Is " + newpassword; } else { TempData["Message"] = "Hey, avoid random request on this page."; } } else { TempData["Message"] = "Username and token not maching."; } return View(); } </code></pre> <p>Step 2 • Right click on the reset password action method and add view  The code for the view page will be as below </p> <pre><code>@{ ViewBag.Title = "ResetPassword"; } &lt;h2&gt;Password Mailed :) &lt;/h2&gt; </code></pre> <p>Step 3 • Go to Solution Explorer...Models... Account Models … Make the following changes. • We create an instance of UserProfile DB Model and implement db.webpages_Memberships’ as DbSet.Use ‘webpages_Memberships’ as a model.</p> <pre><code>public class UsersContext : DbContext { public UsersContext() : base("DefaultConnection") { } public DbSet&lt;UserProfile&gt; UserProfiles { get; set; } public DbSet&lt;webpages_Membership&gt; webpages_Memberships { get; set; } } [Table("webpages_Membership")] public class webpages_Membership { [Key] public int UserId { get; set; } public DateTime CreateDate { get; set; } public string ConfirmationToken { get; set; } public bool IsConfirmed { get; set; } public DateTime LastPasswordFailureDate { get; set; } public int PasswordFailuresSinceLastSuccess { get; set; } public string Password { get; set; } public DateTime PasswordChangeDate { get; set; } public string PasswordSalt { get; set; } public string PasswordVerificationToken { get; set; } public DateTime PasswordVerificationTokenExpirationDate { get; set; } } </code></pre> <p>Step 4 • Add the Random Password Generation Function to the account controller • This method when called will generate a random password for the user </p> <pre><code> private string GenerateRandomPassword(int length) { string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!@$?_-*&amp;#+"; char[] chars = new char[length]; Random rd = new Random(); for (int i = 0; i &lt; length; i++) { chars[i] = allowedChars[rd.Next(0, allowedChars.Length)]; } return new string(chars); } </code></pre> <p>Step 5 • Add the Send Email Function in account controller. • This function will send first mail to user when user clicks on recover button on forgot password form. The first mail contains the reset password link. When user clicks on the link. User will be redirected to the reset password page. Again the new password will be mailed to the user. • You need to put in your email address in place of XXXXX@gmail.com and write your password.</p> <pre><code>private void SendEMail(string emailid, string subject, string body) { System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(); client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; client.EnableSsl = true; client.Host = "smtp.gmail.com"; client.Port = 587; System.Net.NetworkCredential credentials = new System.Net.NetworkCredential("xxxxx@gmail.com", "password"); client.UseDefaultCredentials = false; client.Credentials = credentials; System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); msg.From = new MailAddress("xxxxx@gmail.com"); msg.To.Add(new MailAddress(emailid)); msg.Subject = subject; msg.IsBodyHtml = true; msg.Body = body; client.Send(msg); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload