این راه حل برای نسخه های قبلی core هم کار میکند.
مقدمه: به شخصه من زیاد با Identity کار نمی کردم و روش خودم پیاده سازی می کردم. اما استفاده از Identity مزیت های زیادی دارد که مهمترین مزیتها امنیت بالا و کد نویسی کمتر هست.
در چند مرحله ما Identity سفارشی سازی می کنیم.ابتدا یک پروژه با پیش Identity پیش فرض درست می کنیم.
برای این کار دو کلاس User و Role میسازیم و به ترتیب از کلاس های IdentityUser<TKey> و IdentityRole<TKey> ارثبری میکنند. برای مثال:
public class Role:IdentityRole<Guid> { public string Description { get; set; } }
در کلاس بالا ما به کلاس Role Identity علاوه بر فیلدهای خودش مت فیلد Description هم اضافه کردیم. همچنین کلید اصلی Primarykey جدول هم Guid انتخاب کردیم. همین کار را هم برای جدولUser تکرار میکنیم با این تفاوت که از IdentityUser ارثبری کرده است.
نکته مهمی که وجود دارد این هست که کلید های اصلی هر دو جدول User و Role باید از یک نوع باشند.
اگر از پروژه ای با Identity پیشفرض استفاده میکنید خودش از IdentityDbContext اثربری کرده ، اگر میخواهید به پروژه فعلی اضافه کنید باید بجای اثربری از DbContext
باید از IdentityDbContext اثربری کنید ولی نکته ای که وجود دارد این است که باید مدل های User و Role خودمان را به IdentityDbContext معرفی کنیم. برای این کار کافیست :
IdentityDbContext<User, Role, Guid>
کلاس ها به علاوه نوع کلید اصلی را به IdentityDbContext به صورت بالا معرفی میکنیم.
همچنین بخش مهم این است که باید base.OnModelCreating(modelBuilder); در ابتدای OnModelCreating قرار داشته باشد:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); ....
اگر از پروژه با Identity پیشفرض استفاده کنید کد زیر را خواهید دید:
services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
اگر هم که از Identity پیشفرض استفاده نمیکنید که اصلا کد بالا رو نمیبینید! . به هر حال . باید کد بالا،به کد زیر تغییر ، یا آن را اضافه کنید:
services.AddIdentity<User,Role>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
کاری که کردیم اینکه بجای AddDefaultIdentity از AddIdentity با مدل ها و کلید اصلی خودمان استفاده کردیم.
اگر از پروژه پیشفرض استفاده می کنید با اجرای برنامه به خطا زیر بر می خورید:
InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.UserManager [Microsoft.AspNetCore.Identity.IdentityUser]' has been registered.
در واقع Identity ما سفارشی سازی شده! دلیل این بخش مربوط به پروژه پیشفرض و view با نام _LoginPartial.cshtml میشود. دربالای این view دو دستور Inject هست که باید اصلاح شوند:
@inject SignInManager<IdentityUser> SignInManager @inject UserManager<IdentityUser> UserManager
همانطور که مشخص هست از IdentityUser که مدل پیشفرض Identity هست استفاده میشود باید با مدل خودمان جایگزین کنیم!:
@using Domain.Models.Identity @inject SignInManager<User> SignInManager @inject UserManager<User> UserManager
نکته namespace هم که using شده را می توانید به فایل _ViewImports.cshtml منتقل کنید!
این ساده ترین حالت سفارشی سازی بود. برای سفارشی سازی دیگر جداول Identity کافیست مانند User و Role کلاس های آنها را بنویسیم و به IdentityDbContext اضافه کنیم:
public class ApplicationDbContext : IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
(کد بالا کاملترین حالت ممکن یعنی سفارشی سازی همه جدول ها هست)
و در فایل startup
services.AddIdentity<User, Role, Guid>(option => { option.Stores.ProtectPersonalData = true; option.User.RequireUniqueEmail = true; option.Password.RequireDigit = true; option.Password.RequireLowercase = false; option.Password.RequireUppercase = false; option.Password.RequireNonAlphanumeric = false; option.SignIn.RequireConfirmedEmail = true; }) .AddUserStore<AppUserStore>() .AddRoleStore<AppRoleStore>() // .AddUserValidator<AppUserValidator>() // .AddRoleValidator<AppRoleValidator>() .AddUserManager<AppUserManager>() .AddRoleManager<AppRoleManager>() .AddSignInManager<AppSignInManager>() .AddErrorDescriber<AppErrorDescriber>() .AddClaimsPrincipalFactory<AppUserClaimsPrincipalFactory>() .AddDefaultTokenProviders();
تمام !
نکته: جداول پروژه تون هم با خیال راحت اضافه کنید همه جداول (Identity و پروژه شما) در یک دیتابیس ایجاد میشوند.