آرمان
آرمان
خواندن ۵ دقیقه·۵ سال پیش

سفارشی کردن Identity در DotnetCore3.1

این راه حل برای نسخه های قبلی core هم کار میکند.

مقدمه: به شخصه من زیاد با Identity کار نمی کردم و روش خودم پیاده سازی می کردم. اما استفاده از Identity مزیت های زیادی دارد که مهمترین مزیتها امنیت بالا و کد نویسی کمتر هست.

در چند مرحله ما Identity سفارشی سازی می کنیم.ابتدا یک پروژه با پیش Identity پیش فرض درست می کنیم.

مرحله اول ساخت مدل های User و Role با کلید دلخواه هست

برای این کار دو کلاس 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 باید از یک نوع باشند.

مرحله دوم اضافه کردن مدل ها به DbContext

اگر از پروژه ای با 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); ....

مرحله سوم درست کردن فایل Startup

اگر از پروژه با Identity پیشفرض استفاده کنید کد زیر را خواهید دید:

services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();

اگر هم که از Identity پیشفرض استفاده نمیکنید که اصلا کد بالا رو نمیبینید! . به هر حال . باید کد بالا،به کد زیر تغییر ، یا آن را اضافه کنید:

services.AddIdentity<User,Role>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();

کاری که کردیم اینکه بجای AddDefaultIdentity از AddIdentity با مدل ها و کلید اصلی خودمان استفاده کردیم.

مرحله آخر درست کردن View

اگر از پروژه پیشفرض استفاده می کنید با اجرای برنامه به خطا زیر بر می خورید:

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 و پروژه شما) در یک دیتابیس ایجاد میشوند.

custom identitydotnetcore 3 1entityframework 3 1
یک برنامه نویس که هرآنچه را که یاد میگیرد در دفترچه یادداشت ویرگولیش یادداشت میکرد(!) حتی یک خط ! تا درصورت نیاز به آن رجوع کند...
شاید از این پست‌ها خوشتان بیاید