اینجا داریم با داده های تستی کار میکنیم

اینجا توی تصویر بالایی چون db context داریم ، داریم با دیتا بیس کار میکنیم

نکته ای که هست اینه که در مورد 4 ام که پایینی هستش ما اومدیم و awite رو پاک کردیم و در آخرش هم اومدیم از result استفاده کردیم که همین کار باعث شده که تابع async تبدیل بشه به sync که این کار اشتباه است

اینجا ما داریم با استفاده از result اومدیم و تابع async رو تبدیل کردیم به sync

با استفاده از task run اومدیم و بلاک کد به صورت async اجرا میشه

خوب توی کد بالا ما از دیتابیس استفاده نکردیم و اومدیم با task run اون رو به صورت async در آرودیم

دقت داشته باشیم که برای async کردن یه تابع نیاز داریم که اون اکشنی که میخوایم از نوع اکشن های دیتابیسی باشه ، یعنی این که به طور مثال دیتابیس رو هم اضافه کرده باشیم و چون داریم با collection ها هم استفاده میکنیم باید linq رو هم اضافه کنیم تا بتونیم از تابع های to list async , … و دیگر async ها استفاده کنیم

خوب where , to list , first or defaul اینها ex method هستند که باید system.linq رو به کد اضافه کنیم تا بتونیم ازش استفاده کنیم چرا first or deafult async یا to list aysnc چرا نیست ؟ جواب = چون باید یه ex method اضافه کنیم که برای دیتابیسه ، که میشه sys . ef core هستش

حالا میرسیم به Get all

کد بالا برای استفاده از دیتا بیس هستش ولی کد پایین بدون دیتابیس هستش

مراحل درست کردن Api pure

توی configure اینطوری مینویسیم

یه پوشه به اسم conteoller ایحاد میکنیم و با اسم جمع مدلمون یه کنترلر ازش میسازیم

نکته برای تعیین مسیر به جای api مثلا میتونیم اون کنترلرهایی که مرتبط با یک موضوعی هستند که اینجا به طور مثال api هستش رو بریزیم توی یه فولدر و بعد اسمش رو هم اینطوری بزاریم توی route

خوب دلیل این که از conteoller base استفاده کردیم اینه که این پروژه فقط api هستش و اینجا نمیخوایم View برگردونیم

در کنترلر از controller base اومدیم ارث بری کردیم که میشه پایه ترین کلاس کنترلر ها و داخل کنترلر به یک منبع داده نیاز داریم اینه که میتونه هر چیزی باشه و میتونیم به دو روش این مبنع داده رو وارد کنترلر کنیم یکیش اینه که داخلش بیایم و new اش کنیم که اینطوری محدود به استفاده از همون هستیم فقط و راه دوم DI هستش

خوب یه نکته ای که هست اینه که نوشتن اون api در ادرس اجباری نیستش ولی اگر ، پروژه بزرگ باشه میتونیم به جاش بنویسیم CMS و بقیه اش و …

برای این کار میایم و توی constuctor اون چیزی که میخوایم رو بهش میدیم ، نکته ای که هست اینه که اون چیزی که میخوایم معرفی کنیم باید interface باشه و باید در جایی تعیین کنیم که اگر جایی در برنامه میخواست چیزی رو درست کنه و new کنه که توی ورودیش یه interface هستش به جای اون اینترفیسه بیا و این یکی کلاس رو new کن و ازش استفاده کن ، برای همین میایم توی startup :

خوب نکته ای که هست اینه که این ها دو تا پارامتر میگیرند اولیس اینترفیسه و دومی اون کلاس هستش

تمام توابع رو به صورت async مینویسیم مورد بعدی action result بنویسیم برای این که نوع respose رو میخوایم برگردونیم نوع خروجی رو هم به صورت کامل بنویسیم

قسمت 8

در entity framework مدل های ما poco هستش یعنی لزومی نداره که از اینترفیس یا کلاسی inherit کنند ولی database context اینطوری نیست و باید از dbcontext ارث بری کنه

در ورودی controctor چیزی به نام otions داریم که با استفاده ازش میایم از دنیای بیرون یه سری اطلاعات رو واردش میکنیم مثل connection string

چون اسم مدلمون command هستش میایم با اسم جمع مدلمون رو میسازیم و اسمش رو میزاریم Commands

در ef classic اگر اسم مدل بود Command خودش به صورت اتوماتیک اسم مدل رو commands میزاشت ولی در EF Core هر چیزی اسم گذاری کنیم میشه همون

خوب حالا میخوایم به جای این که بیایم در کنترلر repo رو new کنیم بیایم با DI این کار رو انجام بدیم

برای این کار باید بیایم و به contructor اون رو inject کنیم و بعد ازش استفاده کنیم

برای استفاده ازش باید از transient استفاده کنیم که به ازای هر request یه شی درست بشه

مثلا اگر یه شخصی درخواست داد و بعد از دوباره درخواست داد دوتا شی جدا درست میشه

خوب توی دیتابیس یه سری امکانات خاص داریم به طور مثال این addDbContext کاره همون transient رو داره انجام میده در قسمت بعدی داریم به صورت generic میایم و دیتابیس رو بهش میدیم

خوب بعد توی قسمت option میایم میگیم که میخوایم از sql server استفاده میکنیم

خوب اون configuration از کجا اومده :

خوب همون اول برنامه میخواد اجرا بشه میخواد startup رو اجرا کنه و بعد میبینه که در ورودیش IConfiguration هستش بعد میره به صورت اتوماتیک configuration رو میسازه

اون چیزهایی که ما خودمون میخوایم بسازیم رو میریم توی configuration service مینویسیم ولی موارد built in که برای خوده برنامه است توی startup انجام میشه

نکته ای که هست اینه که Configuration اینجا set نداره ولی در startup اومده set شده ! چجوری ؟

اینجا یه مورد خاص هستش

نکته constant , read only خوب constatnt برای کلاس هستش و Read only برای اشیا هستش ، مورد بعدی اینه که constant ها رو همون موقع که میسازیموشن باید بهشون مقدار اولیه بدیم ، read only هم همون موقع که ساخته میشه باید بهشون مقدار بدیم یا توی constructor

خوب به جای ورژن بالا اینطوری میتونیم بنویسیم :

جلسه 9

برای کامپایل کردن dotnet build استفاده میکنیم

نکته : up در مقابل down هستش

خوب برای حذف کردنش هم از remove استفاده میکنیم

جلسه 10: خوب زمانی پیش میاد که بخوایم برای view که داریم از یه سری model استفاده کنیم برای همین کار میایم توی پوشه ی view models و اون چیزی که میخوایم رو میسازیم به طور مثال اگر ما بخوایم register کردن کاربر رو چک کنیم ممکنه که بگید از user استفاده کنیم برای مدل ، ولی نمیشه چون در چک کردن کاربر ما یه سری فیلد داریم که توی جدول user نیست و ما باید برای این کا اون model که میخوایم برای این کار رو درست کنیم

توی فولدر resources میایم busisness logic رو میاریم قبلا اسمش BLL بوده اینجا ما میخوایم shared busisness رو بنویسیم یعنی ممکنه چند جا استفاده بشه

در پروژه هیچ چیزی نباید به صورت hard code باشه هر متن و عنوان یا موارد دیگه

توی VS code ما resourse ندارد

برای این که میخوایم توی کل پروژه استفاده کنیم میایم public اش میکنیم

نکته : این name ها تبدیل به property میشن اینجا اتفاقی که میوفته اینه که در پشت صحنه میره و یه کلاس درست میکنه و به ازای هر اسمی در name میاد و به پراپرتی میسازه

در نتیجه name ها محدودیت دارند مثلا اسم پراپرتی نمیشه space داشته باشه ولی در قسمت value محدودیتی نداره

ستون comment فقط برای توضیحات خودمون نوشته شده

خوب برای تغییر زبان اینجا کافیه که ستون value رو ترجمه کنیم اینطوری زبان سایت تغییر میکنه

خوب اینجا به صورت اتوماتیک وقتی که شرایطش انجام نشه به صورت دیفالت یه پیغام میده حالا ما میخوایم این پیام رو عوض کنیم

خوب برای این که پیغام به صورت dynamic باشه این کار رو میکنیم : اینجا به حجای اون 0 میاد و اسم اون پراپرتی رو میزاره

اگر اون پراپرتیمون attribute dispaly رو داشته باشه به جای این که اسم اون پراپرتی رو بنویسه میاد پیام اون display رو مینویسه

خوب اینجا میخوایم به

خوب داریم میگیم تایپ ارور از نوع error massage هستش و از نوع resource هستش و در قسمت دوم required که داره key رو میدیم بهش

اینجا magical string داریم که همین باعث میشه که ممکنه به ارور بخوریم

خوب smart resourse رو برای رفع این مشکل استفاده میکنیم حالا یه قابلیتی داریم به اسم name of

وقتی که میرسه به { } میره میبینه و چک میکنه که dispaly داره یا نه ، اگر نداشته باشه عینا اسم propery رو میزاره ولی اگر داشته باشه میره دوباره از روی resourses دوباره میخونه و بعد اون پیغام رو میسازه

قسمت 11

خوب culture در حال حاضر 2 حرفی مثلا fr en fa ,…

و 5 حرفیه fa-IR , en-UK

میرسیم به resourse :

اون آبی ها میشه slave

معمولا اینطوریه که master زبانش انگلیسی باشه و دومی فارسی برای این که دکمه ها رو فارسی کنیم

خوب اگر بخوایم button ها رو دو زبانه کنیم به جای این که new کنیم باید بیایم همونی که هست رو کپی کنیم خوب resourses باید از نوع dot net standard باشه

اگر culter فارسی باشه اول میره توی همون فایل فارسی اگر پیدا کرد برمیداره اگر نه میره از روی master میخونه

نکته : وقتی که از جای دیگه فایل رو میگیریم میخوایم بزاریم توی پروژه نباید designer اش رو کپی کنیم

فقط کافیه که بریم resx رو کپی کنیم و بعد توی Resourse توی visusal studio بیایم و paste کنیم

دو تا layout هم درست میکنیم و براساس culture تغییرش میدیم

جلسه 12

یه فولدر میسازیم به اسم infrastructure و میایم کلاس های reusable رو توش مینویسیم

این کلاس ها همه جای پروژه میتونن استفاده بشن و میتونیم بیایم و در هرجای پروژه که میخوایم customize اش کنیم

خوب name space که داریم توی پروژه میشه namespace خوده پروژه بعد دات و بعد اسم پروژه

پوشه های models , view models و infostructure

میشه name space خوده پروژه دات اسم پوشه

اسم name space رو خوده اون پوشه میزاریم چون که وقتی که بخوایم مثلا پروژه حسابداری داشته باشیم به اسم accounting اینجا میشه accountg . infostructure

در این حالت اگر بخوایم از کلاس های infostructer در حاهای دیگه هم استفاده کنیم دیگه لازم نیست که namespace اش رو عوض کنیم

خوب اولین atrribute رو گذاشتیم برای این که اگر route رو تعیین نکردیم بهمون ارور بده و بعدی اومدیم route رو تعیین کردیم و سومی برای اینه که تعیین کنیم که json ارتباط داره

بعضی از کنترلر ها با دیتابیس کار میکنند یه سری هم نه

این جا مورد استثنا داره میگه که اگر ما پراپرتی رو تعریف کنیم که فقط get داشته باشه میتونیم توی constructor استثنا بهش مقدار بدیم

قسمت 12 تایم 16

خوب database context میره داخل unit of work و این که unit of work معادل database context هستش

خوب DI :

خوب در مباحث دیتابیسی باید از transient استفاده کنیم یعنی به ازای هر کاربر و هر req که ارسال میشه یه instance ازش ساخته بشه اینجا این خط به این معنی هست که هر جایی که در ورودیش از اینترفیس IUnitOfwork استفاده شده بیاد و یه نمونه از Unit of work ساخته بشه و inject بشه

حالا اینجا داره میگه که خوده unit of work یه سری پارامتر های ورودی داره که اینطوری میایم بهش مقدار دهی میکنیم

خوب توی اسم ها view model ها شبیه به همون dto ها هستند چون همون کار رو دارن میکنن

خوب برای ساختنش View model مینویسیم آخرش

اینجا به طور مثال اون قسمت هایی که توسط user داره پر میشه ، اون قسمتی هایی هم که توسط سرور باید پر بشه هم توسط سرور پر میشه و در نهایت کل این اطلاعات return میشه

خودمون یه کلاس برای برگردوندن نتایج ساختیم :

خوب اینجا جای models.application میتونیم از resultWithData و بعد models.application استفاده کنیم

قسمت 13

اول on action executing و بعد action و بعد on action executed میشد

خوب middleware ها قبل از ورود به action اتفاق میوفتد یعنی بعد از آخرین middleware میره وارد action میشه و بعد همون مسیر رو برمیگرده

در قسمت بالا ما یه middleware داریم که گفته هر request که به آدرس / اومد بهش پیام hello word رو بفرستیم

هر چیزی غیر از آدرس / بنویسیم کار نمیکند

خوب این کد بالا داره این رو میگه که هر req ای با هر verb به هر آدرسی زده شد بیا و hello world رو برگردون

خوب middleware ها اگر run باشند یه کاری رو انجام میدن و تمام میشه و سراغ middleware بعدی نمیره

خوب حالا مدل بعدی :

خوب اینجا داره میگه که بعد از این که middleware اولی انجام شد بره بعدی که همون next هستش در نسخه های قدیمی از next invoke استفاده میکنیم

نکته ای که هست اینه که middleware بعدی میشه app run و میره داخلش کار رو انجام میده و بعد هم تمام میشه و این قسمتش خیلی مهمه چون برمیگرده میره سراغ دستورات بعدی next که در قسمت بالایی نوشتیم

اینجا دستوری نوشته نشده ولی اگر نوشته شده بود زیره await next میشد

توی این حالت هم ما hello word 1 , 2 رو میبینیم

وقتی که arrow function بیشتر از یه مورد ورودی داره باید از پرانتز استفاده کنیم در غیر این صورت نمیخواد

خوب نتیجه به این شکل میشه :

خوب یه middleware داریم به اسم map که داریم اینجا ازش استفاده میکنیم به این صورت که اگر /test رو بزنیم میره و greeting رو اجرا میکنه

حالا اینجا حالتی که پیش میاد اینه که وقتی که ما /test رو نزدیم میره hello world رو اجرا میکنه ، ولی وقتی که /test رو میزنیم میره greeting رو اجرا میکنه و دیگه app . run رو اجرا نمیکنه

حالا اگر بخوایم app run هم بعدش اجرا بشه باید next رو توی greeting مینویشتیم

خوب اینجا فرض کنید که توی فولدر wwwroot اومدیم و یه فایل index.html گذاشتیم

**

حالا میخوایم بهش دسترسی پیدا کنیم ولی همچنان داره بهمون hello world نشون میده

خوب این middleware میاد نگاه میکنه ببینه که فایلی با اون اسمی که درخواست شده رو داریم یا نه ، اگر وجود داشت فایل رو میده ، اگر وجود نداشت میره بعدی

دقت باید داشته باشیم که ترتیب این middleware ها به چه صورت است و این که وقتی که run داشته باشیم یعنی انجام میشه و تمام ولی use ادامه داره

وقتی که break point میزاریم برای تست middleware با این که یه بار req زدیم ولی دو بار واردش میشه ، علتش اینه که مثلا وقتی که یه صفحه html رو درخواست میکنیم ، این میاد و fav icon رو هم باهاش میفرسته

برای همین بهتره که root پروژه fav icon رو داشته باشیم

قسمت 14

کلاس که قراره middleware باشه نباید از کلاس دیگه inherit شده باشه و نه از اینترفیسی

نکته اش اینه که باید constructor ای بنویسیم که ورودیش از جنس request delegate باشه

مرحله ی بعد نوشتن تابع invoke هستش که باید async باشه و چون خروجی نداره فقط میزنیم task

اگر void هستش خروجی :

خوب حالا چطوری میتونیم به کدمون بگیم که از این middleware استفاده کن از use middleware استفاده میکنیم

خوب خودمون میخوایم middleware static رو درست کنیم :

خوب یه نکته ای که داره اینه که ما اومدیم تعریف کردیم که اگر آدرس خالی بود برو به middleware بعد برای همین next رو نوشتیم و بعدش اومدیم return رو زدیم چون اگر برگشت هم کاری نداریم ، برای همین return اش کردیم

خوب اینجا داریم میگیم که بعد از / برو بردار هر چی بود رو

و css/site.css رو برمیداره میریزه توی path

توی mvc کلاسیک داریم sever . map pad رو داشتیم ولی توی core دیگه نداریمش

چون نیاز داریم به آدرس فیزیکی باید از host envitoment content root path استفاده کنیم

خوب حالا اگر خواستیم با این ها یه آدرس کامل بسازیم :

خوب برای همین از combine استفاده میکنیم و اون میاد این داستان این / ها رو در درست کردن ادرس حل میکنه

بیایم یه extention method بنویسیم برای استفاده از middleware ها

خوب حالا برای این که extestion کنیم باید چند تا کار انجام بدیم : اول این که static اش کنیم بعد public اش میکنیم قبل از اولین پارامتر ورودی این رو مینویسیم - اسم اون کلاسی که میخوایم بهش extent کنیم

اون هایی که کنار مکعبشون فلش داره extention method هستند و به صورت built in نبود اند و خوده microsoft اومده در جای دیگه ای بهشون اضافه کرده

آخر این قسمت راجه به middleware excption handling صحبت میکنه

قسمت 15

موضوع cors :

به خاطر مباحث security اتفاقی که میوفته اینه که اگر req از سمت سایتی به غیر از y.com به سمت x.com بره سرور اون رو جواب نمیده ، حتی میتونیم تعیین کنیم که فقط get ها رو جواب بده

خوب توی این حالت که هم بک اند داریم و هم فرانت اند باید بزنیم که چند تا پروژه با هم روی حالت run قرار بگیرند

خوب توی تنظیمات برای cors ما میایم و قسمت register , login رو برای همه باز میزاریم ولی بقیه ی قسمت ها که کارهای مربوط به admin هست رو میبندیم و میگیم که فقط از یه ip و با یه سری تنظیمات خاص میتونه بهش دسترسی پیدا کنه

خوب حالا مثلا برای این که بخوایم cors توی کنترلر که مرتبط با login , register فقط عمل کنه به صورت attribute میایم بالاش مینویسیم

قسمت 16 مشکلی که identity داره اینه که باید user رو بر اساس استاندارد microsft بسازیم ، آقای تصدیقی یه dtx security داره که باهاش میشه سطوح دسترسی رو بعد از این که سایت رو اوردیم بالا روش انجام بدیم

یعنی قابلیت authorize و role دادن به یوز ها

خوب میخوایم بعد از این که سایت رو آپلود کردیم ، حالا میخوایم یه اکشنی رو جلوش رو بگیریم و بگیم که فقط اون هایی که لاگین کردن فقط بهش دسترسی دارن و یا بلعکس و …

توی library microst همش به شکل هارد کد هستش ولی کامپوننت ما قابلیت کاستومایز شدن داره

توی ورژن های قدیمی session داشتیم که این ها یک سری اعداد صحیح بودن که sequensial بودن اولین نفر که وارد میشد بهش یه آی دی میداد و بعد میومد توی ram سرور ذخیره اش میکرد و به کلاینت هم میفرستادش مثلا میشد 17 بعد اون کلاینت هر درخواستی که میفرستاد میگفت که من 17 هستم و بعد سرور بهش سرویس رو میداد و این seeion id توی cookie ها ذخیره میشد و کافی بود که طرف بره و اون رو از 17 به 18 مثلا تغییر بده اینطوری میشد یه نفر دیگه

توی web form این ها تبدیل شدن به guid که یه سری اعداد رندوم هستن

بعدش ماکروسافت اومد هم Seeion و هم authorization رو اورد که در دل هم بودن یعنی دو تا id داشت

یعنی اگر seeion id داشت یعنی لاگین کرده و اگر seeion id نداشت یعنی لاگین نکرده و بعد id یکی دیگه

توی سایت های قدیمی هم بود اونجا که اسم ما رو میزد ولی به چیزی دسترسی نداشتیم و یا به یه چیزا دسترسی داشتیم ولی اسممون نبود برای این که timeout اشون متفاوت بودش

در این شرایط باید logut میکردم و بعد login میکردیم که این دو تا id با هم sync میشد

بعدش اومد idennity رو با authrization , autorazation رو اورمد

خوب فکر کنید که توی یه سازمانی 100 تا پروژه هست و اگر یک پرسنل توی 100 تا این ها باید لاگین میکرد و یکی بهش دسترسی میداد ولی این کاری که ما میخوایم بکنیم یه تفاوتی داره

حالا اگر ما idenity server داشته باشیم این قضیه فرق میکنه و اون طرف وقتی که وارد میشه همه دسترسی هاش اوکی میشه یعنی دسترسی ها و نقش ها همه پرسنل در یک سرور باشه و بیاد این رو انجام بده برای تمام سامانه هایی که دارن

اون شخص میاد لاگین میکنه و بعد یه token میگیره

و بعد اون شخص با اون توکن همه جا میره ، یا دسترسی هاش توی همون توکن هستش یا میره یه جایی چک میشه

مشکلی که داشتیم با session این بود که میومد اون id رو توی ram قرار میداد و مشکل این جا پیش میومد این بود که وقتی چند تا سرور میزاستیم و حالا اینجا ممکن بود اون شخصی که درخواست میده id اش توی این سرور نباشه

ما این کار رو میکردیم برای این که بتونیم load balance انجام بدیم و ممکنه ما توی یه سرور دیگه login کنیم و بعد درخواست بعدی رو به یه سرور دیگه میفرستادیم

اینجوری seeion in memory داشتیم و بعد برای حل این مشکل رو میبردیم همه رو توی database حالا مشکلی که پیش میومد این بود که حالا اینجا این سرور میشد bottle neck و مشکل داشتیم و مشکل بعدی اینه که توی Ram خیلی سریع تر ما میتونیم اطلاعات رو بخونیم تا بریم توی دیتابیس

خوب اول توی node اومد بعدش توی جاهای دیگه jwt میشه جوت این میاد یه json درست میکنه و میتونیم توش هر مدل پراپرتی رو قرار بدیم role , claim , … و بعد میاد این رو signed میکنه

وقتی که ما hash میکنیم یه اطلاعاتی رو مطاقا نمیتونیم به اصلش اون رو برگردونیم و این یعنی ما اینجا encription , decription نداریم

نکته ی بعدی signd میشه یعنی ecript نمیکنه خوب همه فکر میکنن که jwt یه چیزه enript شده ولی اینطوری نیست همون string که به اسم توکن میگیریم رو میتونیم توی سایت jwt بنویسیم و بهمون بگه اطلاعات توش چیه همه ی اطلاعات هستش

اون string که ما میبنیم یه مفهمومی داره به اسم base 64 و اون توکن میتونه بر اساس base 64 بیاد و برسیم به همون json ولی داستانی که داره اینه که این stirg میاد و Signed میشه و زیرش امضا میشه

اگر امضای الکترونیکی بر مبنای 50 ملیون باشه میایم چک میکنیم که ببینیم این امضا signed شده هم درسته و باهاش میخونه یا خیر

اگر این درست نبود پس یعنی داده دستکاری شده

اون چیزی که سمت سرور درست میشه اون بر مبنای enription symetric or asymetric اون رو میاد signed میکنه و در ادامه اش میزاره

هیچوقت اطلاعات محرمانه رو در jwt نزارید مثلا password نباید توی jwt باشه

درخواست میدیم و اون توکن میره توی سروری که خودش این رو ساخته و بعد میاد چک میکنه که این دیتا با اون توکن ، امضا اش میخونه یا خیر

خوب اول میاد یوزر و پسورد رو چک میکنه اگر اوکی بود میاد و ی توکن بهش میده

تمامی اطلاعات هویتی کاربر در jwt هستش ولی چون signed شده است کلید این که بخوایم signed کنیم این اطلاعات رو فقط توی سرور هستش و نگهداری میشه

حتی اگر توکن هم داشته باشیم مثلا role رو از یوزر تبدیلش کنیم به admin و بفرستیم سمت سرور ، سرور میفهمه که این اطلاعات با هم نمیخونه

اون هایی که داخلش هست ، یعنی بالایی داره از پایینیه استفاده میکنه

یه سری nuget ها به یه سری دیگه نیاز دارن برای اجرا شدن

برای sign کردن یه کلید نیاز داریم

اینجا خیلی جالبه ، به جای این که بیایم و یه dto یا view model درست کنه که این جا user رو بدون passsword ارسال کنیم ، اومدیم از serilization json ignore استفاده کردیم ، این یعنی این که وقتی که این کلاس دیتاش میخواد تببدلیل به json بشه ، این رو ignore میکنه و اصلا serilization روش انجام نمیده

اگر این کار و نکنیم باید یه کلاس دیگه درست کنیم به اسم user dto و بعد بیایم با auto mapper تمام فیلد هایی user رو به user dto مپ ککنیم ولی در پروژه های بزرگ این اشتباهه

قسمت 17

خوب

هر attribute که مینویسیم باید از system . attribute ارث بری کرده باشه هر attributr که مینویسیم باید آخر اسمش به attributr منتهی بشه

ولی توی نوشتنش اینطوری مینویسیم :

خوب اینجا چیزی که داره میگه اینه که این attr رو میشه هم برای class استفاده کرد و هم برای متد

اگر ما بالای یه کلاس بیایم Attr بزاریم برای تمامی قسمت هایی که توی اون کلاس هست اعمال میشه

هدف ما اینه که بیایم یه کاری کنیم که بالای هر action اومدیم این authorize رو نوشتیم باید طرف برای دسترسی لاگین کرده باشه

خوب برای این که به این قضیه برسیم باید از یه اینترفیسی هم استفاده کنیم که اسمش IAuthorized fileter باید استفاده کنیم

خوب بعدش اومدیم متد این انترفیس رو پیاده سازی کردیم : خوب ورودی میاد و context میگیره و این context یعنی هر یوزری که میاد توی سایت این رو داره و یه سری اطلاعات مربوط به خودش داخل این هست

زمانی که طرف login کرده و بعد درخواست یه Action رو میده که attr که authroize دداره رو میده بعدش ما میایم توکنی که این یوزر باهاش لاگین کرده رو میگیریم ازش و برای backend ارسالش میکنیم

در middleware میایم اون توکن رو شناسایی میکنیم که سالمه و همه چیزش اوکیه ، اگر اوکی بود میریم شی اون user رو از دیتابیس میخونیم و بعدش میایم به مجموعه اطلاعاتی که توی http context هستش این user رو هم اضافه میکنیم

بعدش میره توی فیلتر و بعد میره توی action و …

توی این عکس بالا هم گفته که بره اون درخواستی که از سمت کلاینت میاد رو بره چک کنه ببینه که پارامتری به اسم uuser توش داره یا نه و اگر وجود داره بیاد cast اش کنه به model user

این جوری هم میشه cast کرد ولی احمقانه است چون که اگر به جای user مثلا country اگر توی اون شی ما بود - این باعث ارور در پروژه میشد

خوب بعدش گفتیم که اگر رفتیم چک کردیم و دیدیم که user برابر با null بود باید بهش پیام unathorized رو بدیم

خوب میایم اینطوری میسازیم :

توی mvc classic تنظیمات ما یه xml بود به اسم web config که توی نسخه ی جدید شده json و فرقشون اینه web config نوعش flat بود ولی توی json میتونیم درختی و nested پارامتر ها و تنظمیات رو بنویسیم

اکر این ساختار رو براش کلاس بسازیم میتونیم تعریف کنیم که از app setting بخونه و بعد مپ میکنه توی اون شی و دیگه لازم نیست که دونه دونه بخونیم و بعد ازش استفاده کینم

و اینجا یه چیزی داریم به اسم secret key و یه چیزی داریم به اسم token expires in min و باید با همین املا و کلمه این دو تا نوشته شود و برای همین هم اومدیم توی main به همین اسم این ها رو تعریف کردیم

بعدش یه پوشه میسازیم به اسم view models و بعد یه پوشه درست میکنیم ب اسم users

میخوایم برای یه Action به اسم login بیایم و یه view model درست کنیم خوب این action login داخل کدوم controller قرار داره ؟ میگیم کنترلر users اسم اون Action که میخوایم براش view model بنویسیم چیه ؟ login خوده login یه ورودی داره یه خروجی ، ورودی میشه Req و خروجی میشه Res و به کلمه ی View model هم باید ختم بشه

اینجا تعییرن کردیم کخه view model مون فقط user name و pass رو داشته باشه و براش required هم گذاشتیم

خوب حالا میخوایم توی Res بعد از این که کلاینت لاگین کرد چه اطلاعاتی رو بفرستیم براش

حالا کلاینت میتونه یه اپلیکشن blazor باشه یا اپ موبایل یا …

این ها رو میفرتسم و این که اون token همونیه که با jwt میخوایم بسازیمش

خوب ما این جا constructor نوشتیم که زمانی که user و token رو بهش میدی ، خودش بره اون پراپرتی ها رو مفدار دهی بکنه

و اگر اون یوزری که این درخواست رو میفرسته null باشه باید بهش خطا بدیم که شما login نکردی

اگر یه کلاسی داریم که یه سری از fild هاش reuqired هستش به جای Defualt constructor بیایم یه controctor براش بنویسیم با اون وردی هایی که اجباری هستش

حالا میخوایم service ها رو بنویسیم که معمولا business توش هستش

ما میتونیم یه کلاس درست کنیم و همه رو با هم inject کنیم ولی بهترش اینه که بیایم اول یه interface درست کنیم و بعد بیایم کلاس رو بسازیم و بعد توی di اعلام میکنیم که ورودی یه کلاسی اگر این interface بود بیا و این کلاس رو بساز و inject کن بهش

اینجا میخوایم id یوزر رو بدیم و خودش رو تحویل بگیریم میخوایم یه تابعی داشته باشیم به اسم get all که فهرست همه ی user ها رو بگیریم

خوب ما توی user service میخوایم از یه سری از اطلاعات توی App setting استفاده کینم برای همین اومدیم از Ioption استفاده کردیم و توی constructor اوردیمیش

خوب اینجا امدیم ب صورت تستی یه سری دیتا رو ساختیم ، اینجا گفتیم که اگر اون user برابر با null بود بیاد این آبجکت رو بسازه و اون رو برگردونه

خوب اینجا اگر میخواستیم از database استفاده کنیم باید از Database context استفاده میکردیم ، ولی اینجا اومدیم از model. user استفاده کردیم که در مرحله قبل اومدیم seed اش کردیم

خوب میرسیم به login

خوب اگر این قسمت رو رد کنه باید بیایم چک کنیم ببینیم که user name , pass درست ارسال شده یا خیر

خوب برای همین میایم میگیم ک بیا و برگرد و usr که شبیه به این user هستش رو بهمون بده اومدیم to lower اش هم کردیم و هر دو تاشون رو to lower کردیم

خوب حالا اگر user رو پیدا نکرد

حالا اگر پیداش کرد :

اینجا میایم و چک میکنیم pass رو با اونی که توی دیتابیس هستش و اینجا ignore cse رو گذاشتیم fasle که این یعنی این که بزرگ و کوجیک تاثیر داره

خوب اینحا وظیفه اش اینه که بیاد و یه توکن درست کنه و گفتیم که در ورودی بیاد user رو بگیر و کلید رو و …

خوب از main setting که توش secrt key داشتیم اومدیم اینجا استفاده کردیم

برای Sign کردن میریم و اون sercet key رو برمیداریم و میایم تبدیلش میکنیم به آرایه ای از بایت ها

چون برای Encription ما نیاز داریم که اون کلید به صورت byte باشه

بعد میایم بهش اون کلیده رو میدیم و ازش یه symetric key میگیریم

و بعد الگوریتیم که میخوایم باهاش singed کینیم رو تعیین میککینم :

و اینجا هم نوشته که singuture هستش

بعدش اومیدم اینطوری

اومیدیم گفتیم که میخوایم اطلاعات رو sign کنیم و بعد کلید و بعد هم الگوریتیم رو بهش میدیم و خودش درستش میکنه

خوب حالا مخوایم تعیین کنیم که داخل خوده توکن چه چیزهایی قراره باشه

خوب میتونه توش claim باشه ، که این ها میتونه با شخصیت باشه مثل مثلا اجازه ی دسترسی به ثبت فلان سند یا میتونه فقط اطلاعات کاربر باشه مثلا اسم و فامیل و …

خوب توی اون دو خط پایین کامنت ها ما داریم از type of استفاده میکنیم که اینطوری ما strongly type هستیم این با اون بالایی فرقی نداره ، فرقش در type safty شون هستش

میتونیم خودمون کلید تعریف کنیم ولی یه سری کلید هم built in توش هست که میتونیم ازش استفاده کینم

مثلا name

خوب

خوب اینه ها هم تشرفاتی هستند

میخوایم اعلام کنیم که کسی که این توکن رو خلق کرده یا همون issuer میشه مثلا سرور فلان توی دامین فلان درست کرده ،

خوب یه چیزه دیگه هم هست که میتونه اینجا کاربردی باشه مثلا وقتی که میدیم به سایت شناسه کاربری رو درست کنه مثلا autho 0 که مثلا 100 تا سامانه توی یه جا و 50 تا سامانه توی یه جای دیگه که همه ی اینهها برای یه سازمان هستش رو میتونه هندل کنه

اونجا issuer معنی داره

خوب audinec میشه همون پروژه شرکت خودمون اسمش

خوب توکن رو درست میکنیم یه Expire date هم بزاریم

خوب 24 ساعت اوکیه ولی 20 خیلی خوبه

خوب برای این که این شی که بیاد sign رو انجام بده و اون داستان ها نیاز داریم به jwt security token handler

و حالا اون رو ساختیم jwt security token handler رو بعدش بهش میگیم که بر اساس اون شی که اون بالا نوشته شده create token رو انجام بده

خوب حالا اون Securoty token که بهمون میده قالب json داره بهمون میده که این همونی که میریم توی سایت jwt میزنیم بهمون همه چیزشو میگه ولی ما میایم توی خط بعدی میزنیم و تبدلیلش میکنیم به string که بفرستیمش به user

خوب حالا میایم برای مدل خروجی که login داره اینطوری مینویسیم ، خوب میایم new میکنیم view models users رو که اون توی پارامتر های ورودیش یه user داشت و یه token که اینجا داریم بهش میدیم

خوب میرسیم به کنترلر

اولین Attr برای اینه که توی دسته api controller ها قرار بگیره و بعدیش برای اینه که بتونه route انجام بشه روش و چون داریم api میتونیسیم به جای controller از controller base اومدیم inherit کردیم

اینجا اومدیم از user service استفاده کردیم ، پس اینجا ما نیاز داریم بهش پس باید از di استفاده کنیم برای همین هم اومیدم یه constructor تعریف کردیم و ازش استفاده کردیم

اینجا چون نداریم null داده

اون قسمت ابی میشه امضا کار

خوب اینجا اومدیم به جای اون بالایی اومدیم iaction reuslt برگردونیدم که باهاش یه status code هم برگردونیم

خوب حالا میخوایم کامل ترش کنیم و میایم نوع اون iaction result رو هم تعیین کردیم

خوب اینجا داریم تعریف میکنیم خروجی تابع login میتونه این دو حالت باشه یا تایپ 200 هستش و جنسش از نوع login response view mode یا 400 با تایپ error view model

خوب جالا توی middleware میخوایم ببینیم که اصلا توکنی با req ارسال شده یا خیر ، توکن ایا valid هست یا خیر ، اگر vlid هست آیا زمان داره یا خیر اگر همه این ها اوکی بود ایا این یوزر که اعلام کرده که داره رو ما هنوز توی دیتابیس داریم ؟ حالا اگر داریمش توی دیتابیس میریم اون رو برمیدارم و میزاریمش توی context عه

خوب req میاد بعد میره توی mid بعد توی mid توکن رو استخراج میکنیم بعدش میره توی attr (یا همون سره Action ) اونجا چک میشه که این یوزره به این قسمت دسترسی داره یا نه ، حالا اگر دسترسی داشت تازه وارد action میشه

اگر هم که Attr نداشت که وارد Action میشه

خوب توی mid یه constructor مینوشتیم که حداقل یه next لازم داشت

حالا اینجا هم از option میخوایم استفاده کنیم ، اورمدیمش

داخل mid باید یه تابعی بنویسیم به اسم invoke , و داخلش اومدیم user service رو هم بهش inject کردیم

اون توکنی که قراره بیاد توی هدرهاش هست

خوب body میشه json

خوب این body یه هدر هم داره که معمولا ما توکن میزاریم توی هدرش

اینطوری هم میشه ولی خوب نیست

خوب اونچیزی هم که توی هدر Set میشه برای این قضیه اسمش

خوب داریم میگیم که برو توی هدر رو ببین که آیا چیزی به این اسم وجود داره یا نه ، بعد بریزش توی request headres

میخوایم bearer توکن رو از توش استخراح کنیم اینطوری میایم و space رو split میکنیم و اخرش رو جدا میکنیم اون توکن نهایی رو به ما میده

یه قسمت دیگه هم داریم به اسم authoriathon که این هم توی هدر set میشه 14:51

بعد گفتیم که اگر null یا null string بود برو کار بعدی و کاری نداشته باش این یعنی این که توی قسمت context هیچ اتفاقی نمیوفته یعنی توی context دیگه نمیره user رو اضافه کنه و خالی میمونه

حالا اکر مخالف null بود میره داخل این if عه که اونجا میایم میگیم که بیا با این token که برو توش رو نگاه کن و برو user اش رو بگیر و بعد برو توی دیتابیس چکش کن ، اگر پیداش کردی و اوکی بود بیا اون رو بچسبون به context ، خوب ما اینجا context و user service رو میفرستیم و توکن و میفرستیم و یکی هم کلید رو میفرستیم که بره با این کلید چک کنه ببینه signed اش درسته یا خیر

خوب بعدش میره توی این تابع بالایی که برای چک کردنش میایم از Validate token استفاده میکنیم و یه پارامتری هم بهش set میکنیم : خوب اینجا میخوایم sign in key رو میخوایم چک کنیم برای همین true دادیمش

خوب بعدش میخوایم issuer sign in key رو محاسبه کنیم که برای این کار میایم از همون symetric security key استفاده میکنیم که اونجا key اش در بالاتر درست کردیم

اینجا هم اکگر این رو ننویسیم دیگه مفهوم validation و expiration time کار نمیکنه و از بین میره ، اینجا داره تاریخ رو صفر میکنه و زمان رو

خوب حالا میگه که بیاد و چک کنه ببینه که این validation token از جنس jwt security token هستش یا نه
خوب اگر به هر دلیلی مشکل داشت که هیچی یا expire شده باشه

برای همین کل این تابعی که داره چک میکنه رو توی try catch گذاشته

حالا اگر توکن null نبود ، میایم claim هاش رو از توی اون توکن میاریم بیرون، خوب اون چیزی که نیاز داریم name id یا همون id که user داره

خوب حالا اگر اون user id مشکل داشت دوباره Retuen میکنیم :

خوب حالا اگر user id اوکی بود میره داخل : و پیداش میکنیم اینطوری

اگر هم نبود که دوباره retun میکنیم

خوب حالا اگر همه ی اینها اوکی بود دیگه میاد توی context یه آیتم به اسم user میزاریم و = میزارمیش با dounded user

خوب ما از این توی on authenticatin ازش استفاده میکنم :

حالا میریم برای یکی از این action ها این Attr رو میزاریم

در حالت درست