Alıştırma - Identity’yi Özelleştirme
Önceki ünitede, özelleştirmenin ASP.NET Çekirdek Kimlik'te 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"
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.Account.Manage.Index
profil yönetimi sayfasıdır. Bu sayfa bu ünitenin ilerleyen bölümlerinde değiştirilmiştir.Account.Register
, kullanıcı kayıt sayfasıdır. Bu sayfa bu ünitede de değiştirilmiştir.Account.Manage.EnableAuthenticator
veAccount.ConfirmEmail
yapı iskelesi yapılmıştır ancak bu ünitede değiştirilmez.
İ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:
- 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
Uzatmak IdentityUser
Kullanıcılarınızın adlarını depolamak için size yeni bir gereksinim verilir. Varsayılan IdentityUser
sınıf ad ve soyad özellikleri içermediğinden sınıfını RazorPagesPizzaUser
genişletmeniz gerekir.
dosyasında aşağıdaki değişiklikleri Areas/Identity/Data/RazorPagesPizzaUser.csyapın:
FirstName
veLastName
özelliklerini ekleyin:using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Identity; namespace RazorPagesPizza.Areas.Identity.Data; 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 null atanamaz 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 null atanamaz 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" role="alert"></div> <div class="form-floating mb-3"> <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 mb-3"> <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 mb-3"> <input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" /> <label asp-for="Input.Email">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>
UserManager.GetUserAsync(User)
null atanabilir RazorPagesPizzaUser
bir nesne döndürür. null-koşullu ?.
işleç, ve LastName
özelliklerine yalnızca RazorPagesPizzaUser
nesne null değilse erişmek FirstName
için kullanılır.
Profil yönetimi formunu özelleştirme
Yeni alanları kullanıcı kayıt formuna eklediniz, ancak mevcut 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. Değişikliklerinizi kaydedin.
<form id="profile-form" method="post"> <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div> <div class="form-floating mb-3"> <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 mb-3"> <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 mb-3"> <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; } /// <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> [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. Değişikliklerinizi 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-posta gönderenini yapılandırma
Uygulamayı ilk kez test edişiniz, bir kullanıcıyı kaydettiniz ve ardından kullanıcının e-posta adresini onaylama benzetimini yapmak için bir bağlantıya tıklamıştınız. Gerçek bir onay e-postası göndermek için uygulamasını oluşturup IEmailSender bağımlılık ekleme sistemine kaydetmeniz gerekir. İşleri basit tutmak için, bu ünitedeki uygulamanız aslında Basit Posta Aktarım Protokolü (SMTP) sunucusuna e-posta göndermez. Yalnızca e-posta içeriğini konsola yazar.
E-postayı konsolda düz metin olarak görüntüleyeceksiniz çünkü oluşturulan iletiyi HTML ile kodlanmış metni dışlayacak şekilde değiştirmeniz gerekir. Alanlar/Kimlik/Sayfalar/Hesap/Register.cshtml.cs bölümünde 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 RazorPagesPizza\Services 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 dünyadaki bir uygulamada,
SendEmailAsync
bir dış posta hizmetine veya e-posta göndermek için başka bir eyleme bağlanır.Program.cs vurgulanmış çizgileri 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 olarak
IEmailSender
kaydederEmailSender
.
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 uygulamasını ile
dotnet run
çalıştırın.Tarayıcınızda uygulamaya gidin. Oturum açtıysanız Oturumu kapat'ı seçin.
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.Kaydolduktan sonra Kayıt onay ekranına yönlendirilirsiniz. Terminal bölmesinde, aşağıdakine benzer konsol çıkışını bulmak için yukarı kaydırın:
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'daki 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+Shift E tuşlarına+basın.
SELECT UserName, Email, FirstName, LastName FROM dbo.AspNetUsers
Aşağıdakine benzer sonuçlar içeren 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 Heinrich Şemaya ve
LastName
eklemedenFirstName
ö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 Merhaba! 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ştirmişsiniz. Onay e-postasını da özelleştirmişsiniz. Bir sonraki ünitede, Kimlik'te çok faktörlü kimlik doğrulamasını uygulama hakkında bilgi edineceksiniz.