ASP.NET Core MVC Login and Registration with Identity

栏目: IT技术 · 发布时间: 4年前

内容简介:The rest will be handled by ASP.NET Core Identity UI. It already contains razor view pages and backend codes for an authentication system. But that’s not what we want in most of the cases.So in this tutorial, let’s look how to customize the ASP.NET Core Id

In this article, we discuss how to implement ASP.NET Core MVC user authentication and registration with Identity.UI.

Sub-topics discussed :

  • How to add ASP.NET Core Identity to an existing project.
  • Customize ASP.NET Core Identity .
  • Identity.UI Design Customization.
  • Next Step.

Background

ASP.NET Core MVC with user authentication can be easily accomplished using ASP.NET Core Identity UI. While creating the MVC project, you just need to select Authentication as Individual User Accounts.

ASP.NET Core MVC Login and Registration with Identity

The rest will be handled by ASP.NET Core Identity UI. It already contains razor view pages and backend codes for an authentication system. But that’s not what we want in most of the cases.

So in this tutorial, let’s look how to customize the ASP.NET Core Identity.

Create an ASP.NET Core MVC Project

First of all, I will create a brand new .Net Core MVC application without any authentication selected. then ASP.NET Core Identity can be added to the project with the help of the Identity Scaffolding template.

In Visual Studio 2019, Go to File > New > Project (Ctrl + Shift + N). From New Project window, Select Asp.Net Core Web Application.

ASP.NET Core MVC Login and Registration with Identity

Once you provide the project name and location. A new window will be opened as follows, Select Web Application(Model-View-Controller), uncheck HTTPS Configuration and DO NOT select any authentication method. Above steps will create a brand new ASP.NET Core MVC project.

ASP.NET Core MVC Login and Registration with Identity

Add ASP.NET Core Identity to Existing Project

To add ASP.NET Core Identity to the existing project, right-click on the project. Add > New Scaffolded Item . from the opened window, select Identity from the left panel and click on Add. It’ll open up another window as shown below.

ASP.NET Core MVC Login and Registration with Identity

With this window, we are trying to override selected operations from Identity. Here I’ve selected Login and Register to demonstrate, to you how much extend you can customize this library. Default _Layout.cshtml is selected for the Identity pages. New class is mentioned for DbContext and User (rather than typing class name directly in text-field, use plus button on right). Finally, click on Add. then the new Identity Area will be added with selected pages and related files.

Now update Startup.cs file as bellow.

Copy to Clipboard
...

public void ConfigureServices(IServiceCollection services)
{
    ...
    //to be added
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...

    app.UseRouting();

    //to be added
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        //to be added
        endpoints.MapRazorPages();
    });
}

ASP.NET Core Identity.UI uses Razor pages for UI. Hence in ConfigureServices, we’ve to call AddRazorPages from services. Identity Contains following Routes,

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Register
  • etc

To add these routes into the app, Inside Configure function, while calling UseEndpoints function we’ve to call MapRazorPages function. UseAuthentication is called to enable authentication. Now, if you navigate mentioned Identity URLs, you could see corresponding interface. we’ve not yet created Database for the app, so form submission won’t work yet.

Customize ASP.NET Core Identity

First of all, I want to add the first and last name of user in user model. that we can do inside our new model class file- /Areas/Identity/Data/ApplicationUser.cs.

Copy to Clipboard
public class ApplicationUser : IdentityUser
{
    [PersonalData]
    [Column(TypeName ="nvarchar(100)")]
    public string FirstName { get; set; }

    [PersonalData]
    [Column(TypeName = "nvarchar(100)")]
    public string LastName { get; set; }
}

As mentioned in /Areas/Identity/IdentityHostingStartup.cs file, this Identity will be using connection string – AuthDbContextConnection. which is saved in appSettings.json file. If you want to change SQL Server instance or DB. you can do that. I use a difference instance and DB.

Copy to Clipboard
"ConnectionStrings": {
    "AuthDbContextConnection": "Server=(local)\\sqlexpress;Database=MVCAuthDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  }

Now we can create the physical DB through DB Migration. From Solution Explorer, select the project, go to Tools>NuGet Package Manager > Package Manager Console. Then execute the following commands one by one.

Copy to Clipboard
Add-Migration "InitialCreate"
Update-Database

After successful DB Migration, Along with other Identity tables, inside AspNetUsers, you could see columns for First Name and Last Name.

Design Customization

First of to add visual flavors into the app, Font Awesome and Google Font-‘Roboto’ stylesheet reference are added to MVC default layout – Views/Shared/_Layout.cshml.

Copy to Clipboard
...
<head>
    ...
    <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
    <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" rel="preload">
</head>
<div>
    <header>
        <nav>
            <div>
                <a asp-area="" asp-controller="Home" asp-action="Index">Authentication System</a>
                <div>
					//partial layout for logged in user.
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div>
        <main role="main">
            @RenderBody()
        </main>
    </div>
    ..

In this layout, you could see the partial render for _LoginPartial. it shows HTML elements for logged user with logout button. Currently inside the same file, it is showing Login and Register Link in header. we don’t have to show them in header. so update _LoginPartial as shown below.

Copy to Clipboard
@using Microsoft.AspNetCore.Identity
@using Project.Areas.Identity.Data

@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

<ul>
@if (SignInManager.IsSignedIn(User))
{
    <li>
        <a id="manage" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
    </li>
    <li>
        <form id="logoutForm" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
            <button id="logout" type="submit">Logout</button>
        </form>
    </li>
}
</ul>

Now let’s add following css rules in global style sheet as follows – wwwroot/css/site.css.

Copy to Clipboard
...
body {
    font-family: 'Roboto', sans-serif;
}

/*for tab control*/
div.login-logout-tab div.card-header {
    padding: 0px 0px 12px 0px;
}

div.login-logout-tab ul.nav-tabs {
    margin: 0px 0px -12px 0px;
}

div.login-logout-tab li.nav-item {
    width: 50%;
}

div.login-logout-tab a.nav-link {
    font-size: 25px;
    color: #495057;
    text-align:center;
}

div.card-content{
    padding : 10px 20px;
}

/*login form*/
div.login-form-icon{
    text-align:center;
}

Now we are going to show login and registration form side by side in a tab control. For that we need a nested layout page for login and register page. So let’s create _AuthLayout.cshtml in /Areas/Identity/Pages. For that right-click on Pages folder, Add>NewItem. Select Razor Layout, name the file as _AuthLayout.cshtml. Replace the file as shown below.

Copy to Clipboard
@{
    Layout = "/Views/Shared/_Layout.cshtml";
}

<div>
    <div>
        <div>
            <div>
                <ul>
                    <li>
                        <a href='/Identity/Account/Login'>Sign In</a>
                    </li>
                    <li>
                        <a href='/Identity/Account/Register'>Sign Up</a>
                    </li>
                </ul>
            </div>
            <div>
                <div>
                    @RenderBody()
                </div>
            </div>
        </div>
    </div>
</div>

@section Scripts{
    @RenderSection("Scripts", required: false) <script>$(function () {
            var current = location.pathname;
            $('.nav-tabs li a').each(function () {
                var $this = $(this);
                if (current.indexOf($this.attr('href')) !== -1) {
                    $this.addClass('active');
                }
            })
        })</script> }

we want to show the tab control like this.

ASP.NET Core MVC Login and Registration with Identity

First of all we’ve main layout(_Layout.cshtml) and then inside that the nested layout(_AuthLayout). In place of @RenderBody(), we’ve to show html from respective razor pages based on URLs. It might be either Login Or Registration page. Inside the script section, based on current URL, we added ‘active’ class to the respective tab header.

User Registration

Now let’s look what we’ve to do in user registration form, which is inside /Areas/Identity/Pages/Account as Register.cshtml . Its a Razor Page not MVC Razor View, there are few differences. It has a view file with extension .cshtml and for handling back-end part, it has a C# file with the extension .cshtml.cs (like we had in old .aspx web form page).

The back-end contains two main functions, OnGetAsync and OnPostAsync to handle GET and POST requests respectively. Inside the registration back-end, we could see InputModel for designing the Registration Form. We’ve to update that for adding controls for first-name and last-name in user registration form.

Copy to Clipboard
public class InputModel
{

    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    ...
}

To save these property values to correspond table – AspNetUsers. Update OnPostAsync,  save the first name and last name to ApplicationUser  instance before inserting into the table.

Copy to Clipboard
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
  ...
  var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email,
                        FirstName = Input.FirstName, LastName = Input.LastName };
  var result = await _userManager.CreateAsync(user, Input.Password);
  ...
}

Now let’s update the razor file as follows.

Copy to Clipboard
@page
@model RegisterModel

@{ ViewData["Title"] = "Register"; }

@{ Layout = "~/Areas/Identity/Pages/_AuthLayout.cshtml"; }

<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
    <div asp-validation-summary="All"></div>
    <div>
        <div>
            <div>
                <label asp-for="Input.FirstName"></label>
                <input asp-for="Input.FirstName" />
                <span asp-validation-for="Input.FirstName"></span>
            </div>
        </div>
        <div>
            <div>
                <label asp-for="Input.LastName"></label>
                <input asp-for="Input.LastName" />
                <span asp-validation-for="Input.LastName"></span>
            </div>
        </div>
    </div>
    <div>
        <label asp-for="Input.Email"></label>
        <input asp-for="Input.Email" />
        <span asp-validation-for="Input.Email"></span>
    </div>
    <div>
        <div>
            <div>
                <label asp-for="Input.Password"></label>
                <input asp-for="Input.Password" />
                <span asp-validation-for="Input.Password"></span>
            </div>
        </div>
        <div>
            <div>
                <label asp-for="Input.ConfirmPassword"></label>
                <input asp-for="Input.ConfirmPassword" />
                <span asp-validation-for="Input.ConfirmPassword"></span>
            </div>
        </div>
    </div>
    <button type="submit">Register</button>
</form>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

I’ve set the layout to _AuthLayout.cshtml  and added form controls for FirstName and LastName. Now if you navigate ‘/Identity/Account/Register’,  you could see the following user registration form.

ASP.NET Core MVC Login and Registration with Identity

If you test the registration form you could see, by default Identity apply some validations to the form controls. you can override them as follows in /Areas/Identity/IdentityHostingStartup.cs file.

Copy to Clipboard
public class IdentityHostingStartup : IHostingStartup
{
    public void Configure(IWebHostBuilder builder)
    {
           ...

            services.AddDefaultIdentity<ApplicationUser>(options => {
                options.Password.RequireLowercase = false;
                options.Password.RequireUppercase = false;
                options.SignIn.RequireConfirmedAccount = false;
            })
                .AddEntityFrameworkStores<AuthDbContext>();
        });
    }
}

By default, there should be at least one lowercase and uppercase character, we’ve disabled that here. The confirmation of email address before first login is also disabled.

Login Form

User authentication or login is handled inside – /Areas/Identity/Pages/Account/Login.cshtml. Now you can update the razor html as follows.

Copy to Clipboard
@page
@model LoginModel

@{ViewData["Title"] = "Login";}


@{
    Layout = "~/Areas/Identity/Pages/_AuthLayout.cshtml";
}
<div>
    <div>
        <i></i>
    </div>
    <form id="account" method="post">
        <div asp-validation-summary="All"></div>
        <div>
            <div>
                <div>
                    <div>
                        <i></i>
                    </div>
                </div>
                <input asp-for="Input.Email" placeholder="Email Address" />
            </div>
            <span asp-validation-for="Input.Email"></span>
        </div>
        <div>
            <div>
                <div>
                    <div>
                        <i></i>
                    </div>
                </div>
                <input asp-for="Input.Password" placeholder="Password" />
            </div>
            <span asp-validation-for="Input.Password"></span>
        </div>
        <div>
            <div>
                <label asp-for="Input.RememberMe">
                    <input asp-for="Input.RememberMe" />
                    @Html.DisplayNameFor(m => m.Input.RememberMe)
                </label>
            </div>
        </div>
        <div>
            <button type="submit">Log in</button>
        </div>
    </form>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Now the login form should look like this.

ASP.NET Core MVC Login and Registration with Identity

Now, this login form should work as we expect. Finally, if you want to redirect the user back to home from login or registration when he/ she is already logged in. you just need to add following if statement in login and register page, inside the function onGetAsync as shown below.

Copy to Clipboard
public async Task OnGetAsync(string returnUrl = null)
{
    if (User.Identity.IsAuthenticated)
    {
        Response.Redirect("/Home");
    }

    ...
}

Finally, you could protect controllers or actions from unauthorized request using Authorize attribute. If there is any unauthorized request made, user will be redirected to login page. I’ve done the same in HomeController.

file – Controllers/HomeController.cs

Copy to Clipboard
[Authorize]
public class HomeController : Controller
{ ... }

Next Step

Here we have tried to override and customize ASP.NET Core Identity library for basic authentication. There are lot of things to be implemented like

  • Email Confirmation
  • Forgot Password
  • Use of JWT Authentication
  • Incorporate with External Authentication like Facebook, Google, etc.

We’ll let you know once we post articles on these topics. If you have any query related to ASP.NET Core Identity let me know.


以上所述就是小编给大家介绍的《ASP.NET Core MVC Login and Registration with Identity》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python Data Structures and Algorithms

Python Data Structures and Algorithms

Benjamin Baka / Packt Publishing / 2017-5-30 / USD 44.99

Key Features A step by step guide, which will provide you with a thorough discussion on the analysis and design of fundamental Python data structures.Get a better understanding of advanced Python c......一起来看看 《Python Data Structures and Algorithms》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具