During we develop a product its always wise to save user time. Think about a login page. Here for Consecutive logins it is much better if we will store user Login Credentials. Using which System will remember the user id and password for next login. In this demo app I am creating a ASP.NET login page with “Remember me” Option.
The logic behind is so simple “During a user login to the System I am storing his/her user id and password to a Cookie. Then under page load event checking is Cookie exists. If so taking user id and password from the Cookie”.
Login.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="Login" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Demo Login App</title> <style type="text/css"> #frmLogin { max-width: 300px; margin: 0 auto; padding-top: 120px; } .formControl { font-family: Verdana; font-size: 12px; } .loginDiv { width:300px; margin-top: 20px; padding: 20px 20px 20px 20px; background-color: #f7f7f7; -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); } .rounded { border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } </style> </head> <body> <form id="frmLogin" runat="server"> <div class="loginDiv rounded"> <div class="formControl"> Email ID <span style="color: Red;">*</span> </div> <div class="formControl"> <asp:TextBox ID="txtEmailID" runat="server" Width="100%"></asp:TextBox> <asp:RequiredFieldValidator ID="rfvEmailID" runat="server" ControlToValidate="txtEmailID" Display="Dynamic" ErrorMessage="Email should not be blank.<br />"></asp:RequiredFieldValidator> <asp:RegularExpressionValidator ID="revEmailID" runat="server" ControlToValidate="txtEmailID" Display="Dynamic" ErrorMessage="Enter a valid Email ID.<br />" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"></asp:RegularExpressionValidator> </div> <div class="formControl"> Password <span style="color: Red;">*</span> </div> <div class="formControl"> <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" Width="100%"></asp:TextBox> <asp:RequiredFieldValidator ID="rfvPassword" runat="server" ControlToValidate="txtPassword" Display="Dynamic" ErrorMessage="Password should not be blank."></asp:RequiredFieldValidator> </div> <asp:Button ID="btnVisitorLogin" runat="server" Text="Login" /> <asp:Label ID="lblMsg" runat="server"></asp:Label> <asp:CheckBox ID="chkNextLogin" runat="server" /> Remember me<a href="#" class="pull-right margin-gap">Need help?</a> </div> </form> </body> </html>
For security reason in Code behind I added my EncryDecry.vb Class from app_code/vb. To execute vb code inside vb folder of app_code I Configured my web.config.
Login.aspx.vb
Imports System.Web.Security Imports System.Data Imports System.Data.SqlClient Partial Class Login Inherits System.Web.UI.Page Dim LoginSqlConn As New SqlConnection(ConfigurationManager.AppSettings.Get("DBKey").ToString()) Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not Page.IsPostBack Then txtEmailID.Focus() 'Check if the browser support cookies If Request.Browser.Cookies Then 'Check if the cookies with name PBLOGIN exist on user's machine If Request.Cookies("PBLOGIN") IsNot Nothing Then 'Pass the user name and password to the VerifyLogin method Me.VerifyLogin(Request.Cookies("PBLOGIN")("UNAME").ToString(), Request.Cookies("PBLOGIN")("UPASS").ToString()) End If End If End If End Sub Protected Sub btnVisitorLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnVisitorLogin.Click 'Decrypt the Password & UserID from Database Dim EncrDecr As New EncryDecry 'Validation Checking Aginest Submission If rfvPassword.IsValid And rfvEmailID.IsValid Then 'Clear Invalid login Message Label lblMsg.Text = "" 'Temporary SecuredUniqueKey Dim UniKey As String = "FCPH6-BPK27-2V4MR" 'Login Checking command in shape of a Stored Procedure that returns Record Count Dim LoginCommand As New SqlCommand("USP_LoginCheck", LoginSqlConn) LoginCommand.CommandType = CommandType.StoredProcedure 'Pass Parameter to Stored Procedure LoginCommand.Parameters.Add("@UserID", SqlDbType.NVarChar, 256).Value = EncrDecr.TripleDESEncode(Trim(txtEmailID.Text), "RC2") LoginCommand.Parameters.Add("@Passcode", SqlDbType.NVarChar, 256).Value = EncrDecr.TripleDESEncode(Trim(txtPassword.Text), "RC2") LoginCommand.Parameters.Add("@SecuredUniqueKey", SqlDbType.NVarChar, 256).Value = UniKey LoginCommand.Parameters.Add("@Status", SqlDbType.NVarChar, 20).Value = "Active" Dim RecordCNT As Integer = 0 Try Dim LoginDataReader As SqlDataReader LoginSqlConn.Open() LoginDataReader = LoginCommand.ExecuteReader If LoginDataReader.Read Then RecordCNT = Convert.ToInt32(LoginDataReader(0).ToString()) End If Catch ex As Exception Response.Write(ex.ToString()) Finally LoginSqlConn.Close() End Try 'Login Checking using the return int value of USP_LoginCheck stored procedure If (RecordCNT = 1) Then Me.VerifyLogin(EncrDecr.TripleDESEncode(Trim(txtEmailID.Text), "RC2"), EncrDecr.TripleDESEncode(Trim(txtPassword.Text), "RC2")) ElseIf (RecordCNT > 1) Then lblMsg.Text = "Invalid Login Credentials" 'Implement 5 Login Attempts of Account Lock ElseIf (RecordCNT < 1) Then lblMsg.Text = "Invalid Login Credentials" 'Implement 5 Login Attempts of Account Lock End If End If End Sub Private Sub VerifyLogin(ByVal UserID As String, ByVal Password As String) Dim LoginDetailsCommand As New SqlCommand("USP_LoginDetails", LoginSqlConn) LoginDetailsCommand.CommandType = CommandType.StoredProcedure 'Pass Parameter to Stored Procedure LoginDetailsCommand.Parameters.Add("@UserID", SqlDbType.NVarChar, 256).Value = UserID LoginDetailsCommand.Parameters.Add("@Passcode", SqlDbType.NVarChar, 256).Value = Password Try Dim LoginDetailsDR As SqlDataReader LoginSqlConn.Open() LoginDetailsDR = LoginDetailsCommand.ExecuteReader If LoginDetailsDR.Read Then Session("UserID") = LoginDetailsDR("PkUid") Session("UserEmail") = UserID Session("FirstName") = LoginDetailsDR("FirstName") Session("LastName") = LoginDetailsDR("LastName") Session("RootPath") = Server.MapPath("../") 'Using form authentication redirect the page to the Default.aspx FormsAuthentication.RedirectFromLoginPage(Trim(txtEmailID.Text), True) 'check if remember me checkbox is checked on login If (chkNextLogin.Checked) Then 'Check if the browser support cookies If (Request.Browser.Cookies) Then 'Check if the cookie with name PBLOGIN exist on user's machine If (Request.Cookies("PBLOGIN") Is Nothing) Then 'Create a cookie with expiry of 30 days Response.Cookies("PBLOGIN").Expires = DateTime.Now.AddDays(30) 'Write username to the cookie Response.Cookies("PBLOGIN").Item("UNAME") = UserID 'Write password to the cookie Response.Cookies("PBLOGIN").Item("UPASS") = Password Else 'If the cookie already exist then wirte the user name and password on the cookie Response.Cookies("PBLOGIN").Item("UNAME") = UserID Response.Cookies("PBLOGIN").Item("UPASS") = Password End If End If End If Else lblMsg.Text = "Invalid Login Credentials" End If Catch ex As Exception Response.Write(ex.ToString()) Finally LoginSqlConn.Close() End Try End Sub End Class
web.config
<?xml version="1.0"?> <configuration> <appSettings> <add key="DBKey" value="Data Source=VIJAYSHANTI; uid=sa; pwd=tiger; database=CodeRND;"/> </appSettings> <connectionStrings/> <system.web> <compilation debug="true" strict="false" explicit="true"> <codeSubDirectories> <add directoryName="VB"/> </codeSubDirectories> </compilation> <authentication mode="Windows"/> </system.web> </configuration>
EncryDecry is the class which helps to convert user id and password to RC2 format. In-case an other user find out the cookie in client machine he or she can’t able to hack the original user.
EncryDecry.vb
Imports System.Security.Cryptography Imports Microsoft.VisualBasic Public Class EncryDecry Public Function TripleDESEncode(ByVal value As String, ByVal key As String) As String Dim des As New System.Security.Cryptography.TripleDESCryptoServiceProvider des.IV = New Byte(7) {} Dim pdb As New System.Security.Cryptography.PasswordDeriveBytes(key, New Byte(-1) {}) des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, New Byte(7) {}) Dim ms As New IO.MemoryStream((value.Length * 2) - 1) Dim encStream As New System.Security.Cryptography.CryptoStream(ms, des.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write) Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value) encStream.Write(plainBytes, 0, plainBytes.Length) encStream.FlushFinalBlock() Dim encryptedBytes(CInt(ms.Length - 1)) As Byte ms.Position = 0 ms.Read(encryptedBytes, 0, CInt(ms.Length)) encStream.Close() Return Convert.ToBase64String(encryptedBytes) End Function Public Function TripleDESDecode(ByVal value As String, ByVal key As String) As String Dim des As New System.Security.Cryptography.TripleDESCryptoServiceProvider des.IV = New Byte(7) {} Dim pdb As New System.Security.Cryptography.PasswordDeriveBytes(key, New Byte(-1) {}) des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, New Byte(7) {}) Dim encryptedBytes As Byte() = Convert.FromBase64String(value) Dim ms As New IO.MemoryStream(value.Length) Dim decStream As New System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write) decStream.Write(encryptedBytes, 0, encryptedBytes.Length) decStream.FlushFinalBlock() Dim plainBytes(CInt(ms.Length - 1)) As Byte ms.Position = 0 ms.Read(plainBytes, 0, CInt(ms.Length)) decStream.Close() Return Text.Encoding.UTF8.GetString(plainBytes) End Function End Class