Create Registration And Login Functionality In ASP.NET Core Using Identity

Introduction

In this article, I will discuss how to create registration and login functionalities in ASP.NET Core web applications using Identity. ASP.NET Core Identity is an API that supports login functionality in ASP.NET Core MVC web application. Login information can be stored in identity when creating a new user account. Identity can be configured with SQL Server database to store user details such as username, password, and email id. So in this article, I will explain how to use identity to register, login and logout of a user account.

ViewModel SignIn

public class SignInVM {
    [Required]
    public string UsernameOrEmail {
        get;
        set;
    }
    [Required, DataType(DataType.Password)]
    public string Password {
        get;
        set;
    }
    public bool RememberMe {
        get;
        set;
    }
}

ViewModel Register

public class RegisterVM {
    [Required, MaxLength(50)]
    public string Username {
        get;
        set;
    }
    [Required, DataType(DataType.EmailAddress)]
    public string Email {
        get;
        set;
    }
    [Required, DataType(DataType.Password)]
    public string Password {
        get;
        set;
    }
    [DataType(DataType.Password), Compare(nameof(Password))]
    public string ConfirmPassword {
        get;
        set;
    }
}

Auth Controller

public class AuthController: Controller {
    private readonly UserManager < AppUser > _userManager;
    private readonly SignInManager < AppUser > _signInManager;
    private RoleManager < IdentityRole > _roleManager {
        get;
    }
    public AuthController(UserManager < AppUser > userManager, SignInManager < AppUser > signInManager, RoleManager < IdentityRole > roleManager) {
        _userManager = userManager;
        _signInManager = signInManager;
        _roleManager = roleManager;
    }
    public IActionResult SignIn() {
            return View();
        }
        [HttpPost]
    public async Task < IActionResult > SignIn(SignInVM signIn, string ReturnUrl) {
        AppUser user;
        if (signIn.UsernameOrEmail.Contains("@")) {
            user = await _userManager.FindByEmailAsync(signIn.UsernameOrEmail);
        } else {
            user = await _userManager.FindByNameAsync(signIn.UsernameOrEmail);
        }
        if (user == null) {
            ModelState.AddModelError("", "Login ve ya parol yalnisdir");
            return View(signIn);
        }
        var result = await
        _signInManager.PasswordSignInAsync(user, signIn.Password, signIn.RememberMe, true);
        if (!result.Succeeded) {
            ModelState.AddModelError("", "Login ve ya parol yalnisdir");
            return View(signIn);
        }
        if (ReturnUrl != null) return LocalRedirect(ReturnUrl);
        return RedirectToAction("Index", "Team", new {
            area = "admin"
        });
    }
    public IActionResult Register() {
            return View();
        }
        [HttpPost]
    public async Task < IActionResult > Register(RegisterVM register) {
        if (!ModelState.IsValid) return View();
        AppUser newUser = new AppUser {
            Email = register.Email,
                UserName = register.Username
        };
        IdentityResult result = await _userManager.CreateAsync(newUser, register.Password);
        if (!result.Succeeded) {
            foreach(var item in result.Errors) {
                ModelState.AddModelError("", item.Description);
            }
        }
        return RedirectToAction("SignIn");
    }
    public async Task < IActionResult > SignOut() {
        await _signInManager.SignOutAsync();
        return RedirectToAction(nameof(SignIn));
    }
}

AppDbContext

public class AppDbContext: IdentityDbContext < AppUser > {
    public AppDbContext(DbContextOptions < AppDbContext > options): base(options) {}
    public DbSet < Team > Teams {
        get;
        set;
    }
}

Models>AppUser

public class AppUser: IdentityUser {
    public string Name {
        get;
        set;
    }
}

Startup ConfigureServices

public void ConfigureServices(IServiceCollection services) {
    services.AddControllersWithViews();
    services.AddDbContext < AppDbContext > (options => options.UseSqlServer(Configuration.GetConnectionString("Default")));
    services.AddIdentity < AppUser, IdentityRole > ().AddEntityFrameworkStores < AppDbContext > ().AddDefaultTokenProviders();
    services.Configure < IdentityOptions > (opt => {
        opt.Password.RequiredLength = 6;
        opt.Password.RequireNonAlphanumeric = false;
        opt.Password.RequireDigit = true;
        opt.Password.RequireLowercase = true;
        opt.Password.RequireUppercase = false;
        opt.User.RequireUniqueEmail = true;
        opt.Lockout.MaxFailedAccessAttempts = 3;
        opt.Lockout.DefaultLockoutTimeSpan = System.TimeSpan.FromMinutes(10);
    });
    services.AddHttpContextAccessor();
    services.ConfigureApplicationCookie(options => {
        options.LoginPath = "/Auth/SignIn";
    });
}

Startup Configure method

app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

Register View

@using Startub.ViewModel
@model RegisterVM
@{
    ViewData["Title"] = "Register";
    Layout = null;
}


<section class="vh-100" style="background-color: #eee;">
  <div class="container h-100">
    <div class="row d-flex justify-content-center align-items-center h-100">
      <div class="col-lg-12 col-xl-11">
        <div class="card text-black" style="border-radius: 25px;">
          <div class="card-body p-md-5">
            <div class="row justify-content-center">
              <div class="col-md-10 col-lg-6 col-xl-5 order-2 order-lg-1">

                <p class="text-center h1 fw-bold mb-5 mx-1 mx-md-4 mt-4">Sign up</p>

                <form method="post" class="mx-1 mx-md-4">

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-user fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="Username" type="text" id="form3Example1c" class="form-control" />
                      <label class="form-label" for="form3Example1c">Your Username</label>
                      <span class="text-danger" asp-validation-for="Username"></span>
                    </div>
                  </div>

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-envelope fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="Email" type="email" id="form3Example3c" class="form-control" />
                      <label  class="form-label" for="form3Example3c">Your Email</label>
                      <span class="text-danger" asp-validation-for="Email"></span>
                    </div>
                  </div>

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-lock fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="Password" type="password" id="form3Example4c" class="form-control" />
                      <label class="form-label" for="form3Example4c">Password</label>
                      <span class="text-danger" asp-validation-for="Password"></span>
                    </div>
                  </div>

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-key fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="ConfirmPassword" type="password" id="form3Example4cd" class="form-control" />
                      <label class="form-label" for="form3Example4cd">Repeat your password</label>
                      <span class="text-danger" asp-validation-for="ConfirmPassword"></span>
                    </div>
                  </div>


                  <div class="d-flex justify-content-center mx-4 mb-3 mb-lg-4">
                    <button type="submit" class="btn btn-primary btn-lg">Register</button>
                  </div>

                </form>
                <div class="text-danger" asp-validation-summary="ModelOnly"></div>
              </div>
              <div class="col-md-10 col-lg-6 col-xl-7 d-flex align-items-center order-1 order-lg-2">

                <img src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-registration/draw1.webp"
                  class="img-fluid" alt="Sample image">

              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

SignIn View

@using Startub.ViewModel
@model SignInVM
@{
    ViewData["Title"] = "SignIn";
    Layout = null;
}

<section class="vh-100" style="background-color: #eee;">
  <div class="container h-100">
    <div class="row d-flex justify-content-center align-items-center h-100">
      <div class="col-lg-12 col-xl-11">
        <div class="card text-black" style="border-radius: 25px;">
          <div class="card-body p-md-5">
            <div class="row justify-content-center">
              <div class="col-md-10 col-lg-6 col-xl-5 order-2 order-lg-1">

                <p class="text-center h1 fw-bold mb-5 mx-1 mx-md-4 mt-4">Sign up</p>

                <form method="post" class="mx-1 mx-md-4">

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-user fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="UsernameOrEmail" type="text" id="form3Example1c" class="form-control" />
                      <label class="form-label" for="form3Example1c">Your Username</label>
                      <span class="text-danger" asp-validation-for="UsernameOrEmail"></span>
                    </div>
                  </div>

                  

                  <div class="d-flex flex-row align-items-center mb-4">
                    <i class="fas fa-lock fa-lg me-3 fa-fw"></i>
                    <div class="form-outline flex-fill mb-0">
                      <input asp-for="Password" type="password" id="form3Example4c" class="form-control" />
                      <label class="form-label" for="form3Example4c">Password</label>
                      <span class="text-danger" asp-validation-for="Password"></span>
                    </div>
                  </div>


                  <div class="d-flex justify-content-center mx-4 mb-3 mb-lg-4">
                    <button type="submit" class="btn btn-primary btn-lg">Login</button>
                  </div>
                  
                </form>
                <div class="text-danger" asp-validation-summary="ModelOnly"></div>
              </div>
              <div class="col-md-10 col-lg-6 col-xl-7 d-flex align-items-center order-1 order-lg-2">

                <img src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-registration/draw1.webp"
                  class="img-fluid" alt="Sample image">

              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">4444444444444

with Logout 

<div style="text-align:end">
    @if(User.Identity.IsAuthenticated)
        {
            <span>@User.Identity.Name</span>
            <a asp-area="default" asp-controller="Auth" asp-action="SignOut">Log out</a>
        }
        else
        {
            <span>Login</span>
        }
</div>