Регистрация пользователя MVC и вход в систему с помощью ASP.NET Core Identity
Регистрация пользователя и аутентификация являются обязательными в любом приложении, если вас мало заботит конфиденциальность. Следовательно, почти вся разработка приложений начинается с модуля аутентификации. В этой статье мы обсудим самый быстрый способ использования ASP.NET Core Identity для входа и регистрации пользователя в новом или существующем приложении MVC.
Обсуждаемые подтемы:
- Как добавить идентификацию ASP.NET Core в приложение MVC.
- Настройте удостоверение ASP.NET Core.
- Настройка дизайна Identity.UI.
- Следующий шаг.
Вступление
ASP.NET Core Identity — это API, который предоставляет как пользовательский интерфейс (UI), так и функции для аутентификации, регистрации, авторизации и т. д. Модули/API, подобные этому, действительно будут полезны и ускорят процесс разработки. Он поставляется с ASP.NET Core Framework и ранее использовался во многих приложениях. Что делает API более надежным и заслуживающим доверия.
ASP.NET Core MVC с аутентификацией пользователя можно легко выполнить с помощью Identity.UI . При создании проекта MVC вам просто нужно выбрать аутентификацию в качестве отдельных учетных записей пользователей.
Остальное будет обрабатываться пользовательским интерфейсом ASP.NET Core Identity. Он уже содержит страницы бритвенного просмотра и внутренние коды для системы аутентификации. Но это не то, что мы хотим в большинстве случаев. мы хотим настроить ASP.NET Core Identity в соответствии с нашими требованиями. Это то, что мы делаем здесь.
Создание проекта ASP.NET Core MVC
Прежде всего, я создам совершенно новое приложение ASP.NET Core MVC без какой-либо аутентификации. Мы могли бы добавить ASP.NET Core Identity позже в проект.
В Visual Studio 2019 выберите «Файл» > «Создать» > «Проект» (Ctrl + Shift + N) . В новом окне проекта выберите ASP.NET Core Web Application.
После того, как вы укажете название проекта и местоположение. Откроется новое окно следующего содержания: выберите «Веб-приложение (модель-представление-контроллер)», снимите флажок «Конфигурация HTTPS» и НЕ выбирайте какой-либо метод аутентификации. Вышеупомянутые шаги создадут новый проект ASP.NET Core MVC.
Добавление удостоверения ASP.NET Core в существующий проект
Чтобы добавить ASP.NET Core Identity в существующий проект, щелкните проект правой кнопкой мыши и выберите « Добавить» > «Новый шаблонный элемент» . В открывшемся окне выберите «Идентификация» на левой панели и нажмите «Добавить». Откроется другое окно, как показано ниже.
С помощью этого окна мы пытаемся переопределить выбранные операции из Identity. Здесь я выбрал «Войти и зарегистрироваться», чтобы продемонстрировать вам, насколько мы можем настроить API. По умолчанию для страниц идентификации выбран файл _Layout.cshtml . Теперь укажите имена классов C# для контекста данных и пользовательской модели, используя кнопку + справа. Наконец, нажмите Добавить. Затем в каталог проекта будет добавлена новая область идентификации с выбранными страницами и соответствующими файлами.
Теперь обновите файл Startup.cs , как показано ниже.
...
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 использует страницы Razor для пользовательского интерфейса. Следовательно ConfigureServices
, в , мы должны позвонить AddRazorPages
из services
. ASP.NET Core Identity содержит следующие маршруты,
- /Идентификация/Учетная запись/Вход
- /Идентификация/Учетная запись/Выход
- /Идентификация/Учетная запись/Регистрация
- так далее
Чтобы добавить эти маршруты в приложение, Configure
функцию Inside, при вызове UseEndpoints
функции мы должны вызвать MapRazorPages
функцию. UseAuthentication
вызывается для добавления аутентификации пользователя в приложение. Теперь, если вы перейдете по упомянутым URL-адресам удостоверений, вы увидите соответствующую страницу интерфейса для входа и регистрации пользователя. Теперь давайте начнем каждый из них один за другим.
Настройка удостоверения ASP.NET Core
Прежде всего, давайте разберемся с регистрацией пользователя для сохранения учетных данных пользователя и данных профиля. Identity API уже определил класс модели IdentityUser
со свойствами
UserName
Email
PhoneNumber
PasswordHash
- для зашифрованного пароля- и т.п.
Давайте добавим еще несколько свойств, таких как имя и фамилия, в класс модели. Для этого мы можем определить новый класс модели ApplicationUser
, который наследуется от класса модели API IdentityUser
.
// new file : /Areas/Identity/Data/ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
[PersonalData]
[Column(TypeName ="nvarchar(100)")]
public string FirstName { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string LastName { get; set; }
}
Существует класс DbContext AuthDbContext
[/Areas/Identity/Data/]. Экземпляр класса будет создан путем внедрения зависимостей ASP.NET Core в IdentityHostingStartup.cs [/Areas/Identity/].
builder.ConfigureServices((context, services) => {
services.AddDbContext<AuthDbContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("AuthDbContextConnection")));
...
}
Строка подключения AuthDbContextConnection
сохраняется в appSettings.json. При необходимости вы можете изменить экземпляр SQL Server или базу данных, как показано ниже.
"ConnectionStrings": {
"AuthDbContextConnection": "Server=(local)\\sqlexpress;Database=MVCAuthDB;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Теперь мы можем создать физическую БД с помощью миграции БД. В обозревателе решений выберите проект, перейдите в Инструменты > Диспетчер пакетов NuGet > Консоль диспетчера пакетов. Затем выполните следующие команды одну за другой.
Add-Migration "InitialCreate"
Update-Database
После успешной миграции БД, наряду с другими таблицами удостоверений, в таблице AspNetUsers вы могли видеть новые столбцы для имени и фамилии.
Настройка дизайна
Прежде всего, чтобы добавить визуальные эффекты в приложение, ссылки на таблицы стилей Font Awesome и Google Font Roboto добавляются в макет MVC по умолчанию — Views/Shared/_Layout.cshml .
...
<head>
...
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" data-rocket-async="style" as="style" onload="this.onload=null;this.rel='stylesheet'" onerror="this.removeAttribute('data-rocket-async')" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Authentication System</a>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
//partial layout for logged in user.
<partial name="_LoginPartial" ></partial>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
..
В этом макете вы могли видеть частичный рендер для _LoginPartial
. он показывает элементы HTML для зарегистрированного пользователя с кнопкой выхода. В настоящее время тот же файл показывает ссылки для входа и регистрации. нам не нужно показывать их в заголовке. поэтому обновите _LoginPartial
, как показано ниже.
@using Microsoft.AspNetCore.Identity
@using Project.Areas.Identity.Data
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
</li>
<li class="nav-item">
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
<button id="logout" type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
</ul>
Теперь давайте добавим следующие правила css в глобальную таблицу стилей [wwwroot/css/site.css] следующим образом.
...
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;
}
Теперь мы собираемся показать форму входа и регистрации рядом во вкладке. Для этого нам нужна вложенная страница макета для страницы входа и регистрации. Итак, давайте создадим _AuthLayout.cshtml в /Areas/Identity/Pages. Для этого щелкните правой кнопкой мыши папку «Страницы», выберите «Добавить»> «Новый элемент». Выберите Razor Layout, назовите файл _AuthLayout.cshtml. Замените файл, как показано ниже.
@{
Layout = "/Views/Shared/_Layout.cshtml";
}
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card login-logout-tab">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link" href='/Identity/Account/Login'>Sign In</a>
</li>
<li class="nav-item">
<a class="nav-link" href='/Identity/Account/Register'>Sign Up</a>
</li>
</ul>
</div>
<div class="card-content">
<div class="col-md-12">
@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');
}
})
})
<!-- put script end tag here !-->
}
мы хотим показать элемент управления вкладками следующим образом.
Прежде всего, у нас есть основной макет (_Layout.cshtml), а затем внутри него вложенный макет (_AuthLayout). Вместо @RenderBody() мы должны показывать html с соответствующих бритвенных страниц на основе URL-адресов. Это может быть страница входа или регистрации. Внутри раздела сценария, на основе текущего URL-адреса, мы добавили класс «активный» к соответствующему заголовку вкладки.
Регистрация пользователя
Теперь давайте посмотрим, что нам нужно сделать в форме регистрации пользователя, которая находится внутри /Areas/Identity/Pages/Account как Register.cshtml . Это Razor Page, а не MVC Razor View, отличий немного. У него есть файл представления с расширением .cshtml, а для обработки серверной части у него есть файл C# с расширением .cshtml.cs (как у нас было на старой странице веб-формы .aspx).
Серверная часть содержит две основные функции OnGetAsync
и OnPostAsync
обрабатывает запросы GET и POST соответственно. Внутри регистрационного бэкенда мы могли видеть InputModel
разработку регистрационной формы. Мы должны обновить это для добавления свойств для имени и фамилии.
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; }
...
}
Чтобы сохранить значения этих свойств в соответствующей таблице AspNetUsers, обновите OnPostAsync
, сохраните имя и фамилию в ApplicationUser
экземпляре перед вставкой в таблицу.
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);
...
}
Теперь давайте обновим файл razor следующим образом.
@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" class="text-danger"></div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.FirstName"></label>
<input asp-for="Input.FirstName" class="form-control" />
<span asp-validation-for="Input.FirstName" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.LastName"></label>
<input asp-for="Input.LastName" class="form-control" />
<span asp-validation-for="Input.LastName" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
@section Scripts {
<partial name="_ValidationScriptsPartial" ></partial>
}
Я установил макет _AuthLayout.cshtml и добавил элементы управления формой для имени и фамилии. Теперь, если вы перейдете по URL-адресу /Identity/Account/Register
, вы увидите следующую форму регистрации пользователя.
Если вы попытаетесь отправить регистрационную форму, вы увидите, что по умолчанию Identity API применяет некоторые проверки к элементам управления формы. вы можете переопределить их следующим образом в /Areas/Identity/IdentityHostingStartup.cs .
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>();
});
}
}
По умолчанию должен быть хотя бы один символ нижнего и верхнего регистра, мы отключили это здесь. Также отключено подтверждение адреса электронной почты перед первым входом в систему.
Форма входа
Аутентификация пользователя или вход в систему обрабатываются в /Areas/Identity/Pages/Account/Login.cshtml. Теперь вы можете обновить файл Razor, как показано ниже.
@page
@model LoginModel
@{ViewData["Title"] = "Login";}
@{
Layout = "~/Areas/Identity/Pages/_AuthLayout.cshtml";
}
<div class="col-md-10 offset-1">
<div class="login-form-icon">
<i class="fas fa-user-circle fa-9x text-secondary"></i>
</div>
<form id="account" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-envelope"></i>
</div>
</div>
<input asp-for="Input.Email" class="form-control" placeholder="Email Address" />
</div>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-lock"></i>
</div>
</div>
<input asp-for="Input.Password" class="form-control" placeholder="Password" />
</div>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
@Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">Log in</button>
</div>
</form>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" ></partial>
}
Теперь форма входа должна выглядеть так.
Наконец, если вы хотите перенаправить уже вошедшего в систему пользователя обратно на домашнюю страницу со страницы входа или регистрации, вам просто нужно обновить onGetAsync
метод с помощью следующих операторов if как на странице входа, так и на странице регистрации.
public async Task OnGetAsync(string returnUrl = null)
{
if (User.Identity.IsAuthenticated)
{
Response.Redirect("/Home");
}
...
}
Наконец, вы можете защитить контроллеры или действия от несанкционированного запроса с помощью Authorize
атрибута. Если будет сделан какой-либо несанкционированный запрос, пользователь будет перенаправлен на страницу входа. Я сделал то же самое в HomeController
.
[Authorize]
public class HomeController : Controller
{ ... }
Следующий шаг
Здесь мы попытались переопределить и настроить библиотеку ASP.NET Core Identity для базовой аутентификации. Есть много вещей, которые нужно реализовать, например
- подтверждение электронного адреса
- Забыл пароль
- JWT-аутентификация
- Добавьте внешнюю аутентификацию, такую как Facebook, Google и т. д.
Все это будет описано в других статьях.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.