به نام خدا
تا پایان قسمت چهارم،سعی ما داشتن یک RestApi ساده بود، از اینجا به بعد بحث ما بر سر امنیت و تولید JWT Token و استفاده از آن در جهت برقرار امنیت Action Method ها خواهد بود.
اول ببینیم فایده استفاده از JWT چیست ؟.
تا چند سال قبل وقتی کاربر لاگین میکرد و همه چیز درست و موفق بود، یک سشن بر روی سرور ایجاد میشد و در کنار آن یک از طریق Cookie ها و مقادیری که در کوکی ذخیره میشد، یک رابطه بین Browser کاربر و سرور برقرار میشد . خوب بد هم نبود. داشت به درستی کار میکرد.
پس چه شد که کم کم متوجه شدیم روند تعریف شده دیگر جواب نیازهای ما را به درستی نمیدهد. دلایل زیاد است، ولی اجازه دهید فقط به یکی از آنها بپردازیم.
فرض کنید این سرور ما توانایی جوابگویی 1000 کاربر را دارد. خوب پس باید سرور اضافه کنیم، خوب پس سرور جدید اضافه میکنیم
با افزایش سرورها ، اگر به شکل دقت کنید، پای لودبلنسر وسط آمد. حالا اگر درخواست ما رفت روی سرور A و سشن پیدا کرد روی آن ولی درخواست بعدی را لودبلنسر فرستاد روی سرور B دیگر روی سرور B اثری از هیچ سشنی نیست و کاربر به صفحه لاگین شوت خواهد شد!. خوب این که نمیشه. پس چه کنیم ؟
یکی از راهها که البته کم خرج نیست و مدیریت آن هم چنان ساده نیست، تصویر زیر است
اگر در این بین یک کش سرور خوشگل بگذاریم تا سشنها آنجا قرار گیرند، خوب این روش آنچنان جالب هم نیست چون باز کش سرور هم قدرت مشخصی دارد و باز مجبور می شویم کش سرور اضافه کنیم و داستان بزرگ و بزرگتر میشود
آیا راه بهتری هست ؟. بله هست. یکی از این راهها تولید یک توکن و ارسال آن به کلاینت است. اینطوری باری روی سرور نداریم، یک String رمز شده داریم که بعد از لاگین به کلاینت ارسال شده و در هر درخواست به سرور ارسال میشود، سرور این رشته را باز میکند و کلیدهای درون آنرا را بازیابی و وضعیت کاربر را مشخص میکند.
پس در Header هر Request ، این توکن به سمت سرور رفته و آنجا بررسی خواهد شد. با داشتن Token عملن دیگر کاری به کار Cookie و ایجاد سشن روی سرور نداریم.
اگر بخواهیم بحث تئوری کنیم، حرف و مطلب برای گفتن زیاد است، لذا بهتر است وارد بحث عملی شده و ببینیم چطور میتوانیم API خود را به JWT Token مسلح و به صورت عملی از آن استفاده کنیم.
در ابتدا، این دو پکیج را به پروژه خود اضافه میکنیم
Microsoft.AspNetCore.Authentication.JwtBearer
Microsoft.AspNetCore.Identity.EntityFrameworkCore
حال باید تنظیمات JWT را در جایی نگه داریم، فکر کنم Appsetting بد نباشد. پس این فایل دست خوش تغییر خواهد شد. تغییرات این فایل به شکل زیر خواهد بود
برای تولید این رشته می توانید از :
https://www.browserling.com/tools/random-string
استفاده کنید
درون پروژه یک فولدر جدید به نام Configuration می سازیم و درون آن کلاسی به نام JwtConfig ایجاد میکنیم
حالا باید به سراغ Startup.cs برویم و تغییرات لازمه را اعمال کنیم
دقت کنید، بخشی که با رنگ سفید مشخص شده قبلن بوده، ولی بقیه را باید به متد ConfigureServices اضافه کنیم تمام و کمال
هنوز کار ما با Startup.cs تمام نشده و الان نوبت متد Configureاست تا تغییرات آن هم اعمال شود
اگر الان پروژه را اجرا و یکی از متدها را مثلن با PostMan صدا بزنیم، خواهیم دید چیزی فرق نکرده و همه چیز مانند قبل است، پس هنوز مراحلی در پیش است تا یک JWT Token تولید و استفاده گردد
در DbContext هم باید تغییراتی به شکل زیر لحاظ شود
کلاسی که از DbContext ما از آن ارث بری میکرد باید عوض شود.
حالا انتظار داریم جداول امنیتی مرتبط با Identity به دیتابیس ما افزوده شود، پس باید باز Migration انجام شود
من در ترمینال این دو دستور را وارد کردم
add-migration "Aut Tables"
و بعد
Update-Database
خوب انجام شد و جداول جدید هم ساخته شدند.
خوب تنظیمات تمام شد، در مرحله بعدی باید کنترلر جدید بسازیم تا روندهای لاگین و.... را پیاده سازی کنیم که البته آنها را بخش بعدی انجام خواهیم داد.