Alıştırma - Identity’yi Özelleştirme
Önceki ünitede özelleştirmenin ASP.NET Core Identity'de nasıl çalıştığını öğrendinsiniz. Bu ünitede Kimlik veri modelini genişletir ve ilgili kullanıcı arabirimi değişikliklerini yaparsınız.
Kullanıcı hesabı verilerini özelleştirme
Bu bölümde, kimlik kullanıcı arabirimi dosyalarını varsayılan Razor Sınıf Kitaplığı yerine kullanılacak şekilde oluşturacak ve özelleştireceksiniz.
Değiştirilecek kullanıcı kaydı dosyalarını projeye ekleyin:
dotnet aspnet-codegenerator identity --dbContext RazorPagesPizzaAuth --files "Account.Manage.EnableAuthenticator;Account.Manage.Index;Account.Register;Account.ConfirmEmail" --userClass RazorPagesPizzaUser --force
Yukarıdaki komutta:
--dbContext
seçeneğiDbContext
sınıfından türetilmişRazorPagesPizzaAuth
sınıfına yönelik bilgileri araca sağlar.--files
seçeneği Identity alanına eklenecek benzersiz dosyaların noktalı virgülle ayrılmış listesini belirtir.--userClass
seçeneği,IdentityUser
sınıfından türetilmişRazorPagesPizzaUser
sınıfının oluşturulmasıyla sonuçlanır.- seçeneği,
--force
Kimlik alanındaki mevcut dosyaların üzerine yazılmasını sağlar.
İpucu
Seçeneğin geçerli değerlerini görüntülemek için
--files
proje kökünden aşağıdaki komutu çalıştırın:dotnet aspnet-codegenerator identity --listFiles
Aşağıdaki dosyalar Areas/Identity dizinine eklenir:
- Data/
- RazorPagesPizzaUser.cs
- Pages/
- _ViewImports.cshtml
- Account/
- _ViewImports.cshtml
- ConfirmEmail.cshtml
- ConfirmEmail.cshtml.cs
- Register.cshtml
- Register.cshtml.cs
- Manage/
- _ManageNav.cshtml
- _ViewImports.cshtml
- EnableAuthenticator.cshtml
- EnableAuthenticator.cshtml.cs
- Index.cshtml
- Index.cshtml.cs
- ManageNavPages.cs
Buna ek olarak,
--force
seçeneği kullanıldığından yukarıdaki komut çalıştırılmadan önce mevcut olan Data/RazorPagesPizzaAuth.cs dosyasının da üzerine yazılır.RazorPagesPizzaAuth
sınıf bildirimi şimdi yeni oluşturulanRazorPagesPizzaUser
kullanıcı türüne başvurur:public class RazorPagesPizzaAuth : IdentityDbContext<RazorPagesPizzaUser>
EnableAuthenticator ve ConfirmEmail Razor sayfaları, modülün ilerleyen bölümlerine kadar değiştirilmese de iskelesi oluşturulmuştur.
içinde Program.csçağrısının
AddDefaultIdentity
yeni Kimlik kullanıcı türüne dikkat edilmesi gerekir. Aşağıdaki vurgulanan değişiklikleri ekleyin. (Okunabilirlik için yeniden biçimlendirilen örnek.)using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using RazorPagesPizza.Areas.Identity.Data; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("RazorPagesPizzaAuthConnection"); builder.Services.AddDbContext<RazorPagesPizzaAuth>(options => options.UseSqlServer(connectionString)); builder.Services.AddDefaultIdentity<RazorPagesPizzaUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<RazorPagesPizzaAuth>(); // Add services to the container. builder.Services.AddRazorPages();
Aşağıdaki vurgulanmış değişiklikleri en üste eklemek için güncelleştirin Pages/Shared/_LoginPartial.cshtml . Yaptığınız değişiklikleri kaydedin.
@using Microsoft.AspNetCore.Identity @using RazorPagesPizza.Areas.Identity.Data @inject SignInManager<RazorPagesPizzaUser> SignInManager @inject UserManager<RazorPagesPizzaUser> UserManager <ul class="navbar-nav">
Yukarıdaki değişiklikler,
@inject
yönergelerindeSignInManager<T>
veUserManager<T>
öğelerine geçirilen kullanıcı türünü güncelleştirir. VarsayılanIdentityUser
türünün yerine artıkRazorPagesPizzaUser
kullanıcısına başvurulur.RazorPagesPizzaUser
başvurularını çözümlemek için@using
yönergesi eklendi.Pages/Shared/_LoginPartial.cshtml, fiziksel olarak Identity alanının dışında bulunur. Bu nedenle, dosya iskele aracı tarafından otomatik olarak güncelleştirilmedi. Uygun değişiklikler el ile yapılmalıdır.
İpucu
_LoginPartial.cshtml dosyasını el ile düzenlemeye alternatif olarak dosya, iskele aracı çalıştırılmadan önce silinebilir. Dosya _LoginPartial.cshtml , yeni
RazorPagesPizzaUser
sınıfa başvurularla yeniden oluşturulur.Ek kullanıcı profili verilerinin alınmasını ve depolanmasını desteklemek için Areas/Identity/Data/RazorPagesPizzaUser.cs dosyasını güncelleştirin. Aşağıdaki değişiklikleri yapın:
FirstName
veLastName
özelliklerini ekleyin:public class RazorPagesPizzaUser : IdentityUser { [Required] [MaxLength(100)] public string FirstName { get; set; } = string.Empty; [Required] [MaxLength(100)] public string LastName { get; set; } = string.Empty; }
Yukarıdaki kod parçacığındaki özellikler, temel alınan
AspNetUsers
tablosunda oluşturulacak ek sütunları temsil eder. Her iki özellik de gerekli olduğundan, bunlara[Required]
özniteliğiyle not eklenir. Ayrıca,[MaxLength]
özniteliği maksimum uzunluk olarak 100 karaktere izin verildiğini belirtir. Temel alınan tablo sütununun veri türü de buna uygun olarak tanımlanır. Bu projede null atanabilir bağlam etkinleştirildiğinden ve özellikler boş değer atanamayan dizeler olduğundan varsayılan değeristring.Empty
atanır.Aşağıdaki
using
deyimini dosyanın en üstüne ekleyin.using System.ComponentModel.DataAnnotations;
Yukarıdaki kod,
FirstName
veLastName
özelliklerine uygulanan veri açıklaması özniteliklerini çözümler.
Veritabanını güncelleştirme
Artık model değişiklikleri yapıldığına göre, veritabanında buna eşlik eden değişiklikler yapılmalıdır.
Tüm değişikliklerinizin kaydedildiğinden emin olun.
Temel alınan veri deposunu güncelleştirmek için EF Core geçişi oluşturma ve uygulama:
dotnet ef migrations add UpdateUser dotnet ef database update
UpdateUser
EF Core geçişi,AspNetUsers
tablosunun şemasına bir DDL değişiklik betiği uyguladı. Aşağıdaki geçiş çıkışı alıntısında görüldüğü gibi, özellikleFirstName
veLastName
sütunları eklendi:info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (37ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE [AspNetUsers] ADD [FirstName] nvarchar(100) NOT NULL DEFAULT N''; info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (36ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE [AspNetUsers] ADD [LastName] nvarchar(100) NOT NULL DEFAULT N'';
EF Core geçişinin
UpdateUser
tablonun şeması üzerindekiAspNetUsers
etkisini analiz etmek için veritabanını inceleyin.SQL Server bölmesinde, dbo üzerindeki Sütunlar düğümünü genişletin. AspNetUsers tablosu.
FirstName
sınıfındakiRazorPagesPizzaUser
veLastName
özellikleri, önceki görüntüdekiFirstName
veLastName
sütunlarına karşılık gelir.[MaxLength(100)]
öznitelikleri nedeniyle her iki sütuna danvarchar(100)
veri türü atandı. null olmayan kısıtlama eklendi çünküFirstName
veLastName
sınıfında boş değer atanamayan dizeler. Mevcut satırlar, yeni sütunlarda boş dizeler gösterir.
Kullanıcı kaydı formunu özelleştirme
ve LastName
için FirstName
yeni sütunlar eklediniz. Şimdi kayıt formunda eşleşen alanları görüntülemek için kullanıcı arabirimini düzenlemeniz gerekir.
Areas/Identity/Pages/Account/Register.cshtml dosyasına aşağıda vurgulanmış işaretlemeyi ekleyin:
<form id="registerForm" asp-route-returnUrl="@Model.ReturnUrl" method="post"> <h2>Create a new account.</h2> <hr /> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-floating"> <input asp-for="Input.FirstName" class="form-control" /> <label asp-for="Input.FirstName"></label> <span asp-validation-for="Input.FirstName" class="text-danger"></span> </div> <div class="form-floating"> <input asp-for="Input.LastName" class="form-control" /> <label asp-for="Input.LastName"></label> <span asp-validation-for="Input.LastName" class="text-danger"></span> </div> <div class="form-floating"> <input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" /> <label asp-for="Input.Email"></label> <span asp-validation-for="Input.Email" class="text-danger"></span> </div>
Yukarıdaki işaretleme ile, Ad ve Soyadı metin kutuları kullanıcı kaydı formuna eklenir.
Areas/Identity/Pages/Account/Register.cshtml.cs dosyasına ad metin kutuları için destek ekleyin.
İç içe geçmiş
InputModel
sınıfınaFirstName
veLastName
özelliklerini ekleyin:public class InputModel { [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "First name")] public string FirstName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "Last name")] public string LastName { get; set; } /// <summary> /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; }
[Display]
öznitelikleri, metin kutularıyla ilişkilendirilecek etiket metnini tanımlar.RazorPagesPizza
nesnesindeFirstName
veLastName
özelliklerini ayarlamak içinOnPostAsync
metodunu değiştirin. Aşağıdaki vurgulanmış satırları ekleyin:public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var user = CreateUser(); user.FirstName = Input.FirstName; user.LastName = Input.LastName; await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); var result = await _userManager.CreateAsync(user, Input.Password);
Yukarıdaki değişiklik,
FirstName
veLastName
özelliklerini kayıt formundaki kullanıcı girişine ayarlar.
Site üst bilgisini özelleştirme
Kullanıcı kaydı sırasında toplanan ad ve soyadı bilgilerini görüntülemek için Pages/Shared/_LoginPartial.cshtml dosyasını güncelleştirin. Aşağıdaki kod parçacığında vurgulanan satırlar gereklidir:
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
RazorPagesPizzaUser user = await UserManager.GetUserAsync(User);
var fullName = $"{user.FirstName} {user.LastName}";
<li class="nav-item">
<a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello, @fullName!</a>
</li>
Profil yönetimi formunu özelleştirme
Yeni alanları kullanıcı kayıt formuna eklediniz, ancak varolan kullanıcıların düzenleyebilmesi için bunları profil yönetimi formuna da eklemeniz gerekir.
Areas/Identity/Pages/Account/Manage/Index.cshtml dosyasına aşağıda vurgulanmış işaretlemeyi ekleyin. Yaptığınız değişiklikleri kaydedin.
<form id="profile-form" method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-floating"> <input asp-for="Input.FirstName" class="form-control" /> <label asp-for="Input.FirstName"></label> <span asp-validation-for="Input.FirstName" class="text-danger"></span> </div> <div class="form-floating"> <input asp-for="Input.LastName" class="form-control" /> <label asp-for="Input.LastName"></label> <span asp-validation-for="Input.LastName" class="text-danger"></span> </div> <div class="form-floating"> <input asp-for="Username" class="form-control" disabled /> <label asp-for="Username" class="form-label"></label> </div>
Ad metin kutularına yönelik desteği sunmak için Areas/Identity/Pages/Account/Manage/Index.cshtml.cs dosyasında aşağıdaki değişiklikleri yapın.
İç içe geçmiş
InputModel
sınıfınaFirstName
veLastName
özelliklerini ekleyin:public class InputModel { [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "First name")] public string FirstName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "Last name")] public string LastName { get; set; } [Phone] [Display(Name = "Phone number")] public string PhoneNumber { get; set; } }
LoadAsync
metodunda vurgulanan değişiklikleri ekleyin:private async Task LoadAsync(RazorPagesPizzaUser user) { var userName = await _userManager.GetUserNameAsync(user); var phoneNumber = await _userManager.GetPhoneNumberAsync(user); Username = userName; Input = new InputModel { PhoneNumber = phoneNumber, FirstName = user.FirstName, LastName = user.LastName }; }
Yukarıdaki kod, profil yönetimi formunun karşılık gelen metin kutularında görüntülenmesi için ad ve soyadı bilgilerinin alınmasına yönelik destek sunar.
Vurgulanan değişiklikleri
OnPostAsync
metoduna ekleyin. Yaptığınız değişiklikleri kaydedin.public async Task<IActionResult> OnPostAsync() { var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } if (!ModelState.IsValid) { await LoadAsync(user); return Page(); } user.FirstName = Input.FirstName; user.LastName = Input.LastName; await _userManager.UpdateAsync(user); var phoneNumber = await _userManager.GetPhoneNumberAsync(user); if (Input.PhoneNumber != phoneNumber) { var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber); if (!setPhoneResult.Succeeded) { StatusMessage = "Unexpected error when trying to set phone number."; return RedirectToPage(); } } await _signInManager.RefreshSignInAsync(user); StatusMessage = "Your profile has been updated"; return RedirectToPage(); }
Yukarıdaki kod, veritabanının
AspNetUsers
tablosunda yer alan ad ve soyadı bilgilerinin güncelleştirilmesine yönelik destek sunar.
Onay e-postası göndereni yapılandırma
Onay e-postasını göndermek için uygulamasını IEmailSender oluşturmanız ve bağımlılık ekleme sistemine kaydetmeniz gerekir. İşleri basit tutmak için uygulamanız aslında bir SMTP sunucusuna e-posta göndermez. Yalnızca e-posta içeriğini konsola yazar.
Konsolda e-postayı düz metin olarak görüntüleyecek olduğunuzdan, oluşturulan iletiyi HTML ile kodlanmış metni dışlayacak şekilde değiştirmeniz gerekir. Alanlar/Kimlik/Sayfalar/Hesap/Register.cshtml.cs içinde aşağıdaki kodu bulun:
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
Şu şekilde değiştirin:
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by visiting the following URL:\r\n\r\n{callbackUrl}");
Gezgin bölmesinde Hizmetler klasörüne sağ tıklayın ve EmailSender.cs adlı yeni bir dosya oluşturun. Dosyasını açın ve aşağıdaki kodu ekleyin:
using Microsoft.AspNetCore.Identity.UI.Services; namespace RazorPagesPizza.Services; public class EmailSender : IEmailSender { public EmailSender() {} public Task SendEmailAsync(string email, string subject, string htmlMessage) { Console.WriteLine(); Console.WriteLine("Email Confirmation Message"); Console.WriteLine("--------------------------"); Console.WriteLine($"TO: {email}"); Console.WriteLine($"SUBJECT: {subject}"); Console.WriteLine($"CONTENTS: {htmlMessage}"); Console.WriteLine(); return Task.CompletedTask; } }
Yukarıdaki kod, iletinin IEmailSender içeriğini konsola yazan bir uygulamasını oluşturur. Gerçek bir uygulamada,
SendEmailAsync
bir dış posta hizmetine veya e-posta göndermek için başka bir eyleme bağlanır.Program.cs dosyasında vurgulanan satırları ekleyin:
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using RazorPagesPizza.Areas.Identity.Data; using Microsoft.AspNetCore.Identity.UI.Services; using RazorPagesPizza.Services; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("RazorPagesPizzaAuthConnection"); builder.Services.AddDbContext<RazorPagesPizzaAuth>(options => options.UseSqlServer(connectionString)); builder.Services.AddDefaultIdentity<RazorPagesPizzaUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<RazorPagesPizzaAuth>(); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddTransient<IEmailSender, EmailSender>(); var app = builder.Build();
Yukarıdaki, bağımlılık ekleme sisteminde bir
IEmailSender
olarak kaydedilirEmailSender
.
Kayıt formundaki değişiklikleri test etme
Hepsi bu kadar! Şimdi kayıt formundaki değişiklikleri ve onay e-postasını test edelim.
Tüm değişikliklerinizi kaydettiğinizden emin olun.
Terminal bölmesinde projeyi derleyin ve ile
dotnet run
uygulamayı çalıştırın.Tarayıcınızda uygulamaya gidin. Oturumunuz hala açıksa Oturumu kapat seçeneğini belirleyin.
Yeni bir kullanıcı kaydetmek için Kaydolun’u seçip güncelleştirilmiş formu kullanın.
Not
Ad ve Soyadı alanlarındaki doğrulama kısıtlamaları,
InputModel
sınıfınıFirstName
veLastName
özelliklerindeki veri açıklamalarını yansıtır.Kayıt olduktan sonra Kayıt onayı ekranına yönlendirilirsiniz. Terminal bölmesinde yukarı kaydırarak aşağıdakine benzer konsol çıkışını bulun:
Email Confirmation Message -------------------------- TO: jana.heinrich@contoso.com SUBJECT: Confirm your email CONTENTS: Please confirm your account by visiting the following URL: https://localhost:7192/Identity/Account/ConfirmEmail?<query string removed>
Ctrl+tuşunu basılı tutarak URL'ye gidin. Onay ekranı görüntülenir.
Not
GitHub Codespaces kullanıyorsanız, iletilen URL'nin ilk bölümüne eklemeniz
-7192
gerekebilir. Örneğin,scaling-potato-5gr4j4-7192.preview.app.github.dev
.Oturum aç'ı seçin ve yeni kullanıcıyla oturum açın. Uygulamanın üst bilgisi artık şunu içerir: Merhaba [Ad] [Soyadı]!.
VS Code'un SQL Server bölmesinde RazorPagesPizza veritabanına sağ tıklayın ve Yeni sorgu'yu seçin. Görüntülenen sekmeye aşağıdaki sorguyu girin ve çalıştırmak için Ctrl+ ShiftEtuşlarına+ basın.
SELECT UserName, Email, FirstName, LastName FROM dbo.AspNetUsers
Aşağıdakine benzer sonuçlara sahip bir sekme görüntülenir:
UserName E-posta FirstName LastName kai.klein@contoso.com kai.klein@contoso.com jana.heinrich@contoso.com jana.heinrich@contoso.com Jana dili Heinrich FirstName
veLastName
öğelerini şemaya eklemeden önce kaydolan ilk kullanıcı. Bu nedenle ilişkiliAspNetUsers
tablo kaydında bu sütunlarda veri yoktur.
Profil yönetimi formundaki değişiklikleri test etme
Profil yönetimi formunda yaptığınız değişiklikleri de test etmelisiniz.
Web uygulamasında, oluşturduğunuz ilk kullanıcıyla oturum açın.
Profil yönetimi formuna gitmek için Hello, ! bağlantısını seçin.
Not
AspNetUsers
tablosunun bu kullanıcıya yönelik satırıFirstName
veLastName
değerlerini içermediğinden bağlantı düzgün şekilde görüntülenmez.Ad ve Soyadı için geçerli değerleri girin. Kaydet’i seçin.
Uygulamanın üst bilgisi şöyle güncelleştirilir: Merhaba, [Ad] [Soyadı]!.
Uygulamayı durdurmak için VS Code'daki terminal bölmesinde Ctrl+C tuşuna basın.
Özet
Bu ünitede, Özel kullanıcı bilgilerini depolamak için Kimliği özelleştirdiyseniz. Onay e-postasını da özelleştirdiyseniz. Bir sonraki ünitede Kimlik'te çok faktörlü kimlik doğrulamasını uygulamayı öğreneceksiniz.