HI WELCOME TO KANSIRIS

HOW TO RECOVER AND RESET THE FORGOT/LOST PASSWORD IN ASP.NET USING ACTIVATION LINK IN EMAIL ID

Leave a Comment

Recover and reset password in asp.netIntroduction: In this article I am going to explain with example How to get or recover and reset/change/update the password that you forgot or lost by using reset password activation link in email id in asp.net using both C# and VB.Net languages


The concept is very simple. Below are the steps to implement the option of resetting the forgotten password:
  • First User will supply his/her Email Id or User Name and click on submit Button.
  • Supplied username or email address will be checked against the Sql server database table "Tbl_Login" and if username or email id is matched then a unique random code will be generated and updated in the UniqueCode field of the "Tbl_Login" table.
  • Then this generated unique code and the username or email id will be set in the QueryString parameters and a link with this query string will be sent to the email address of the recover password requester.
  • Requester will check his email id and click on the reset password activation link. On clicking he will be redirected to the Reset password page from where he can reset his password.
  • The activation link is for one time use only. Once the password has been updated, it will not show the panel again to reset password.
Implementation: Lets’ create an asp.net web application to understand the concept practically.
  • Create a Database in Sql Server and name it "MyDataBase" and also create a table in that database with the fields and data type as shown below and name it "Tbl_Login"

Column Name
Data Type
Id
Int(primary Key. So set Is Identity=True)
UserName
varchar(100)
EmailId
varchar(100)
Pwd
varchar(50)
UniqueCode
varchar(100)

  • In the web.config file create the connection string in the <configuration> tag to connect our application with the Sql server database as:
<connectionStrings>
    <add name="conStr" connectionString="Data Source=lalit;Initial Catalog=MyDataBase;Integrated Security=True"/>
  </connectionStrings>

Note: Replace the Data Source and the Initial Catalog(i.e. database name) as per your application.
  • We will create two pages. One page "ForgotPassword.aspx" from where user will supply his email id or username to get the reset password activation link on his email address as shown in first image above. And also another page "ResetPassword.aspx" which will be opened on clicking the reset password link provided in the email id for resetting the password as shown in second image above.
Asp.Net C# Section:
  • So add a page and name it “ForgotPassword.aspx” and design the page as:
HTML Source Code: 

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Forgot password ? Recover Password By Email Or User Name example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <fieldset style="width:380px;">
    <legend>Recover Password By Email Or User Name</legend>
    <table>
    <tr>
    <td>UserName : </td><td>
        <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
        </td>
    </tr>
    <tr>
    <td colspan="2">&nbsp;&nbsp;OR</td>
    </tr>
    <tr>
    <td>Email Id : </td><td>
        <asp:TextBox ID="txtEmailId" runat="server"></asp:TextBox><br />
        <asp:RegularExpressionValidator ID="revEmailId" runat="server"
            ErrorMessage="Please enter valid email address"
            ControlToValidate="txtEmailId" Display="Dynamic"
            ForeColor="Red" SetFocusOnError="True"
            ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"></asp:RegularExpressionValidator>
        </td>
    </tr>
    <tr>
    <td>&nbsp;</td><td>
        <asp:Button ID="btnSubmit" runat="server" Text="Submit"
            onclick="btnSubmit_Click" />
        </td>
    </tr>
    <tr>
    <td colspan="2">
        <asp:Label ID="lblStatus" runat="server" Text=""></asp:Label>
        </td>
    </tr>
    </table>
    </fieldset>
   
    </div>
    </form>
</body>
</html>

Note: I have also implemented the necessary validations on the textbox controls using asp.net's validation controls.
Asp.Net C# Code to recover and reset the forgotten or lost password
  • In the Code behind File (ForgotPassword.aspx.cs) write the code as:
First include the following required namespaces:

using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Text;

then write the code on Submit button’s click event as:

protected void btnSubmit_Click(object sender, EventArgs e)
    {
        string uniqueCode = string.Empty;
        SqlCommand cmd = new SqlCommand();
        SqlDataReader dr;
        try
        {
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString);
            if (con.State == ConnectionState.Closed)
            {
                con.Open();
            }
            // get the records matching the supplied username or email id.         
cmd = new SqlCommand("select * from Tbl_Login where UserName COLLATE Latin1_general_CS_AS=@username or EmailId COLLATE Latin1_general_CS_AS=@emailId", con);

            cmd.Parameters.AddWithValue("@username"Convert.ToString(txtUserName.Text.Trim()));
            cmd.Parameters.AddWithValue("@emailId"Convert.ToString(txtEmailId.Text.Trim()));        
            dr = cmd.ExecuteReader();
            cmd.Dispose();
            if (dr.HasRows)
            {
                dr.Read();
  //generate unique code
                uniqueCode = Convert.ToString(System.Guid.NewGuid());
                //Updating an unique random code in then UniquCode field of the database table
                cmd = new SqlCommand("update Tbl_Login set UniqueCode=@uniqueCode where UserName=@username or EmailId=@emailid", con);
                cmd.Parameters.AddWithValue("@uniqueCode", uniqueCode);
                cmd.Parameters.AddWithValue("@username", txtUserName.Text.Trim());
                cmd.Parameters.AddWithValue("@emailid", txtEmailId.Text.Trim());
               
                StringBuilder strBody = new StringBuilder();
                //Passing emailid,username and generated unique code via querystring. For testing pass your localhost number and while making online pass your domain name instead of localhost path.
                strBody.Append("<a href=http://localhost:2464/SampleApplication/ResetPassword.aspx?emailId=" + txtEmailId.Text + "&uName=" + txtUserName.Text + "&uCode=" + uniqueCode + ">Click here to change your password</a>");
               // sbody.Append("&uCode=" + uniqueCode + "&uName=" + txtUserName.Text + ">Click here to change your password</a>");

                System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage("SenderEmailIAddress@gmail.com", dr["EmailId"].ToString(), "Reset Your Password", strBody.ToString());
                //pasing the Gmail credentials to send the email

                System.Net.NetworkCredential mailAuthenticaion = newSystem.Net.NetworkCredential("SenderEmailIAddress@gmail.com""SenderPassword");
              
                System.Net.Mail.SmtpClient mailclient = new System.Net.Mail.SmtpClient("smtp.gmail.com", 587);
                mailclient.EnableSsl = true;
                mailclient.UseDefaultCredentials = false;
                mailclient.Credentials = mailAuthenticaion;            
                mail.IsBodyHtml = true;
                mailclient.Send(mail);
                dr.Close();
                dr.Dispose();
                cmd.ExecuteReader();
                cmd.Dispose();             
                con.Close();
                lblStatus.Text = "Reset password link has been sent to your email address";
                txtEmailId.Text = string.Empty;
                txtUserName.Text = string.Empty;           
            }
            else
            {
                lblStatus.Text = "Please enter valid email address or username";
                txtEmailId.Text = string.Empty;
                txtUserName.Text = string.Empty;
                con.Close();
                return;
            }
        }
        catch (Exception ex)
        {
            lblStatus.Text = "Error Occured: " + ex.Message.ToString();
        }
        finally
        {             
            cmd.Dispose();           
        }
    }
Note: I have used the COLLATE Latin1_general_CS_AS in the above code to check for the exact username or email id match because COLLATE Latin1_general_CS_AS  is used to make the sql queries case sensitive. e.g. if the username is demo and email id is demo@domain.com then if user enters Demo in username or Demo@domain.com in email id field then it will not match and will not fetch the records and a message "Please enter valid email address or username" will be displayed
  • Now add another page and name it “ResetPassword.aspx” and design the page as:
 HTML Source Code:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Reset Password Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Panel ID="ResetPwdPanel" runat="server" Visible="false" >
    <fieldset style="width:400px">
    <legend>Reset Password</legend>   
    <table>
    <tr>
    <td>New password: </td><td>
        <asp:TextBox ID="txtNewPwd" runat="server"></asp:TextBox><br />
        <asp:RequiredFieldValidator ID="rfvNewPwd" runat="server"
            ControlToValidate="txtNewPwd" Display="Dynamic"
            ErrorMessage="Please enter new password" ForeColor="Red" SetFocusOnError="True"></asp:RequiredFieldValidator>
        </td>
    </tr>
    <tr>
    <td>Confirm Passsword: </td><td>
        <asp:TextBox ID="txtConfirmPwd" runat="server"></asp:TextBox><br />
        <asp:RequiredFieldValidator ID="rfvConfirmPwd" runat="server"
            ControlToValidate="txtConfirmPwd" Display="Dynamic"
            ErrorMessage="Please re-enter password to confirm" ForeColor="Red"
            SetFocusOnError="True"></asp:RequiredFieldValidator>
        <asp:CompareValidator ID="cmvConfirmPwd" runat="server"
            ControlToCompare="txtNewPwd" ControlToValidate="txtConfirmPwd"
            Display="Dynamic" ErrorMessage="Password didn't match" ForeColor="Red"
            SetFocusOnError="True"></asp:CompareValidator>
        </td>
    </tr>
    <tr>
    <td>
        &nbsp;</td><td>
        <asp:Button ID="btnChangePwd" runat="server" Text="Change Password"
                onclick="btnChangePwd_Click" /></td>
    </tr>
        <tr>
            <td colspan="2">
                <asp:Label ID="lblStatus" runat="server" Text=""></asp:Label>
            </td>
        </tr>
    </table>
    </fieldset>       
    </asp:Panel>
    <asp:Label ID="lblExpired" runat="server" Text="" style="color: #FF0000"></asp:Label>
    </div>
    </form>
</body>
</html>

  • Now in the code behind file(“ResetPassword.aspx.cs”) write the code as:
First include the following required namespaces:

using System.Data;
using System.Data.SqlClient;
using System.Configuration;

then write the code on page load event and  change password button’s click event as:

SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString);
    SqlCommand cmd = new SqlCommand();
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            SqlDataReader dr;
            try
            {
                //Here we will check from the passed querystring that if the email id/username and generated unique code is same then the panel for resetting password will be visible otherwise not
                cmd = new SqlCommand("select UserName,EmailId,UniqueCode from Tbl_Login        where UniqueCode=@uniqueCode and (EmailId=@emailid or UserName=@username)", con);
                cmd.Parameters.AddWithValue("@uniqueCode"Convert.ToString(Request.QueryString["uCode"]));
                cmd.Parameters.AddWithValue("@emailid"Convert.ToString(Request.QueryString["emailId"]));
                cmd.Parameters.AddWithValue("@username"Convert.ToString(Request.QueryString["uName"]));

                if (con.State == ConnectionState.Closed)
                {
                    con.Open();
                }
                dr = cmd.ExecuteReader();

                if (dr.HasRows)
                {
                    ResetPwdPanel.Visible = true;
                }
                else
                {
                    ResetPwdPanel.Visible = false;
                    lblExpired.Text = "Reset password link has expired.It was for one time use only";
                    return;
                }
                dr.Close();
                dr.Dispose();
            }
            catch (Exception ex)
            {
                lblStatus.Text = "Error Occured: " + ex.Message.ToString();
            }
            finally
            {
                cmd.Dispose();
                con.Close();
            }
        }
    }
    protected void btnChangePwd_Click(object sender, EventArgs e)
    {
        try
        {   // Here we will update the new password and also set the unique code to null so that it can be used only for once.
            cmd = new SqlCommand("update Tbl_Login set UniqueCode='',Pwd=@pwd where UniqueCode=@uniqueCode and (EmailId=@emailid or UserName=@username)", con);
            cmd.Parameters.AddWithValue("@uniqueCode"Convert.ToString(Request.QueryString["uCode"]));
            cmd.Parameters.AddWithValue("@emailid"Convert.ToString(Request.QueryString["emailId"]));
            cmd.Parameters.AddWithValue("@username"Convert.ToString(Request.QueryString["uName"]));
            cmd.Parameters.AddWithValue("@pwd", txtNewPwd.Text.Trim());
            if (con.State == ConnectionState.Closed)
            {
                con.Open();
            }
            cmd.ExecuteNonQuery();
            lblStatus.Text = "Your password has been updated successfully.";
            txtNewPwd.Text = string.Empty;
            txtConfirmPwd.Text = string.Empty;
        }
        catch (Exception ex)
        {
            lblStatus.Text = "Error Occured : " + ex.Message.ToString();
        }
        finally
        {
            cmd.Dispose();
            con.Close();
        }
    }
  ---------------------------------------------------------------------------------------------------

Asp.Net VB Section:

HTML Source Code
  • Design the "ForgotPassword.aspx" as described in the C#.Net section but replace the line
        <asp:Button ID="btnSubmit" runat="server" Text="Submit"
            onclick="btnSubmit_Click" />
With
        <asp:Button ID="btnSubmit" runat="server" Text="Submit" />

Asp.Net VB Code to recover and change the lost password
  • In the code behind file (ForgotPassword.aspx.vb) write the code as:
First of all import the following namespaces

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Text

 Then write the code on Submit button’s click event as:

Protected Sub btnSubmit_Click(sender As Object, e As System.EventArgsHandles btnSubmit.Click
        Dim uniqueCode As String = String.Empty
        Dim cmd As New SqlCommand()
        Dim dr As SqlDataReader
        Try
            Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("conStr").ConnectionString)
            If con.State = ConnectionState.Closed Then
                con.Open()
            End If
            get the records matching the supplied username or email id.        
            cmd = New SqlCommand("select * from Tbl_Login where UserName COLLATE Latin1_general_CS_AS =@username or EmailId COLLATE Latin1_general_CS_AS =@emailId", con)

            cmd.Parameters.AddWithValue("@username"Convert.ToString(txtUserName.Text.Trim()))
            cmd.Parameters.AddWithValue("@emailId"Convert.ToString(txtEmailId.Text.Trim()))
            dr = cmd.ExecuteReader()
            cmd.Dispose()
            If dr.HasRows Then
                dr.Read()
                'generate unique code
                uniqueCode = Convert.ToString(System.Guid.NewGuid())
                'Updating an unique random code in then UniquCode field of the database table
                cmd = New SqlCommand("update Tbl_Login set UniqueCode=@uniqueCode where UserName=@username or EmailId=@emailid", con)
                cmd.Parameters.AddWithValue("@uniqueCode", uniqueCode)
                cmd.Parameters.AddWithValue("@username", txtUserName.Text.Trim())
                cmd.Parameters.AddWithValue("@emailid", txtEmailId.Text.Trim())

                Dim strBody As New StringBuilder()
                'Passing emailid,username and generated unique code via querystring. For testing pass your localhost number and while making online pass your domain name instead of localhost path.
                strBody.Append(("<a href=http://localhost:2464/SampleApplication/ResetPasswordVB.aspx?emailId=" + txtEmailId.Text & "&uName=") + txtUserName.Text & "&uCode=" & uniqueCode & ">Click here to change your password</a>")
                ' sbody.Append("&uCode=" + uniqueCode + "&uName=" + txtUserName.Text + ">Click here to change your password</a>");

                Dim mail As New System.Net.Mail.MailMessage("SenderEmailAddress@gmail.com", dr("EmailId").ToString(), "Reset Your Password", strBody.ToString())
                'pasing the Gmail credentials to send the email
                Dim mailAuthenticaion As New System.Net.NetworkCredential("SenderEmailAddress@gmail.com","SenderPassword")

                Dim mailclient As New System.Net.Mail.SmtpClient("smtp.gmail.com", 587)
                mailclient.EnableSsl = True
                mailclient.UseDefaultCredentials = false
                mailclient.Credentials = mailAuthenticaion
                mail.IsBodyHtml = True
                mailclient.Send(mail)
                dr.Close()
                dr.Dispose()
                cmd.ExecuteReader()
                cmd.Dispose()
                con.Close()
                lblStatus.Text = "Reset password link has been sent to your email address"
                txtEmailId.Text = String.Empty
                txtUserName.Text = String.Empty
            Else
                lblStatus.Text = "Please enter valid email address or username"
                txtEmailId.Text = String.Empty
                txtUserName.Text = String.Empty
                con.Close()
                Return
            End If
        Catch ex As Exception
            lblStatus.Text = "Error Occured: " & ex.Message.ToString()
        Finally
            cmd.Dispose()
        End Try
    End Sub


HTML Source Code:
  • Add a new page and name it “ResetPassword.aspx” and design the page as described in the C#.Net section’s "ResetPassword.aspx" but replace the line
<asp:Button ID="btnChangePwd" runat="server" Text="Change Password"
                onclick="btnChangePwd_Click" />
with
<asp:Button ID="btnChangePwd" runat="server" Text="Change Password” />
 
  • In the Code behind file (ResetPassword.aspx.vb) write the code as:
First import the required namespaces 

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Then write the code as:

Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("conStr").ConnectionString)
    Dim cmd As New SqlCommand()

    Protected Sub Page_Load(sender As Object, e As System.EventArgsHandles Me.Load
        If Not Page.IsPostBack Then
            Dim dr As SqlDataReader
            Try
                'Here we will check from the passed querystring that if the email id/username and generated unique code is same then the panel for resetting password will be visible otherwise not
                cmd = New SqlCommand("select UserName,EmailId,UniqueCode from Tbl_Login" & vbTab & "where UniqueCode=@uniqueCode and (EmailId=@emailid or UserName=@username)", con)
                cmd.Parameters.AddWithValue("@uniqueCode"Convert.ToString(Request.QueryString("uCode")))
                cmd.Parameters.AddWithValue("@emailid"Convert.ToString(Request.QueryString("emailId")))
                cmd.Parameters.AddWithValue("@username"Convert.ToString(Request.QueryString("uName")))

                If con.State = ConnectionState.Closed Then
                    con.Open()
                End If
                dr = cmd.ExecuteReader()

                If dr.HasRows Then
                    ResetPwdPanel.Visible = True
                Else
                    ResetPwdPanel.Visible = False
                    lblExpired.Text = "Reset password link has expired.It was for one time use only"
                    Return
                End If
                dr.Close()
                dr.Dispose()
            Catch ex As Exception
                lblStatus.Text = "Error Occured: " & ex.Message.ToString()
            Finally
                cmd.Dispose()
                con.Close()
            End Try
        End If
    End Sub

    Protected Sub btnChangePwd_Click(sender As Object, e As System.EventArgsHandles btnChangePwd.Click
        Try
            ' Here we will update the new password and also set the unique code to null so that it can be used only for once.
            cmd = New SqlCommand("update Tbl_Login set UniqueCode='',Pwd=@pwd where UniqueCode=@uniqueCode and (EmailId=@emailid or UserName=@username)", con)
            cmd.Parameters.AddWithValue("@uniqueCode"Convert.ToString(Request.QueryString("uCode")))
            cmd.Parameters.AddWithValue("@emailid"Convert.ToString(Request.QueryString("emailId")))
            cmd.Parameters.AddWithValue("@username"Convert.ToString(Request.QueryString("uName")))
            cmd.Parameters.AddWithValue("@pwd", txtNewPwd.Text.Trim())
            If con.State = ConnectionState.Closed Then
                con.Open()
            End If
            cmd.ExecuteNonQuery()
            lblStatus.Text = "Your password has been updated successfully."
            txtNewPwd.Text = String.Empty
            txtConfirmPwd.Text = String.Empty
        Catch ex As Exception
            lblStatus.Text = "Error Occured : " & ex.Message.ToString()
        Finally
            cmd.Dispose()
            con.Close()
        End Try
    End Sub

Run the "ForgotPassword.aspx" page and enter username or email id and click on submit button.It will send reset password link on your email id. Check your email and click on the reset password link. You will be redirected to the "ResetPassword.aspx" page from where you can update your password.
Once updated the reset password link will now redirect to the same "ResetPassword.aspx" page but now you will not be able to update the password because it was for one time use only.

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.