Part 2 - Complete login and registration system in ASP.NET MVC application



Introduction

In the previous video of this article "Complete Login and registration system in asp.net MVC application" We have already done the Part 1: Registration page with email validation & password hashing from where a user will get a verification email in his/her email ID. Here in this video, we will create email verification page for account verification, login page with remember me option  & Logout page.

Ok, Let's start implementing complete login and registration system in ASP.NET MVC application. 

Follow the following steps in order to implement "Part 2: Complete login and registration system in ASP.NET MVC application".

Here In this article, I have used Visual Studio 2015

Step-1: Add a new action in UserController.

What we will do here, we will create a HttpGet Action for verifying the account using the activation code we have sent to user email id when they have successfully submitted the registration page. 

[HttpGet]
public ActionResult VerifyAccount(string id)
{
    bool Status = false;
    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {
        dc.Configuration.ValidateOnSaveEnabled = false; // This line I have added here to avoid 
                                                        // Confirm password does not match issue on save changes
        var v = dc.Users.Where(a => a.ActivationCode == new Guid(id)).FirstOrDefault();
        if (v != null)
        {
            v.IsEmailVerified = true;
            dc.SaveChanges();
            Status = true;
        }
        else
        {
            ViewBag.Message = "Invalid Request";
        }
    }
    ViewBag.Status = Status;
    return View();
}

Step-2: Add an another HttpGet Action for Login.

Here I will add a new Http Get Action in the UserController for getting the login form.

[HttpGet]
public ActionResult Login()
{
    return View();
}

Step-3: Add View for the Login Action

In this example, I have added the table for store user data when submitting for registration.
Login.cshtml
@model RegistrationAndLogin.Models.UserLogin

@{
    ViewBag.Title = "Login";
}
<h2>Login</h2>
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">        
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.EmailID, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.EmailID, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EmailID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.RememberMe, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.RememberMe)
                    @Html.ValidationMessageFor(model => model.RememberMe, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Register Now", "Registration","User")
</div>


@section Scripts{
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
}

Step-4: Add HttpPost Action for submitting Login form.

Here in this action, we will check the provided credential and then we will redirect the user to the ReturnUrl or in the Index action of Home controller.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(UserLogin login, string ReturnUrl="")
{
    string message = "";
    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {
        var v = dc.Users.Where(a => a.EmailID == login.EmailID).FirstOrDefault();
        if (v != null)
        {
            if (!v.IsEmailVerified)
            {
                 ViewBag.Message = "Please verify your email first";
                 return View();
            }
            if (string.Compare(Crypto.Hash(login.Password),v.Password) == 0)
            {
                int timeout = login.RememberMe ? 525600 : 20; // 525600 min = 1 year
                var ticket = new FormsAuthenticationTicket(login.EmailID, login.RememberMe, timeout);
                string encrypted = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
                cookie.Expires = DateTime.Now.AddMinutes(timeout);
                cookie.HttpOnly = true;
                Response.Cookies.Add(cookie);


                if (Url.IsLocalUrl(ReturnUrl))
                {
                    return Redirect(ReturnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                message = "Invalid credential provided";
            }
        }
        else
        {
            message = "Invalid credential provided";
        }
    }
    ViewBag.Message = message;
    return View();
}

Step-5: Add 1 more action in the UserController for Logout.

Here in this action we will remove the authentication cookie for sign out and will redirect the user to the login page.

[Authorize]
[HttpPost]
public ActionResult Logout()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Login", "User");
}

Step-6: Add a new controller.

Now I will add an another controller HomeController.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name HomeController > Select Templete "empty MVC Controller"> Add.

By default, it's already added an Index action in the controller.  We will make it Authorized action by adding [Authorize] attribute for making it accessible only to logged in user.


[Authorize]
public ActionResult Index()
{
    return View();
}

Step-7: Add view for the Index action of HomeController.

Index.cshtml
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

Welcome @HttpContext.Current.User.Identity.Name

@if (Request.IsAuthenticated)
{
    using (Html.BeginForm("Logout","User", FormMethod.Post, new { id="logoutForm"}))
    {
        <a href="javascript:document.getElementById('logoutForm').submit()">Logout</a>
    }
}

Step-8: Update web.config.

Add this below 3 line in your web.config file inside system.web section
<authentication mode="Forms">
      <forms cookieless="UseCookies"  loginUrl="~/user/login" slidingExpiration="true"></forms>
    </authentication>

Step-9: Run Application.

We have done all the steps. Now it's time to run the application. 

Hello ! My name is Sourav Mondal. I am a software developer working in Microsoft .NET technologies since 2010.

I like to share my working experience, research and knowledge through my site.

I love developing applications in Microsoft Technologies including Asp.Net webforms, mvc, winforms, c#.net, sql server, entity framework, Ajax, Jquery, web api, web service and more.