نظرات نظرسنجیها
cmsهای متن باز مبتنی بر asp.net ، سی شارپ و mvc وجود دارد مانند orchard که تو همین سایت هم مطلب دربارش است ... مگه این که بخواهید یک چیز عجیبی بسازید !
در NET Core. به ظاهر دیگر خبری از کلاسهایی مانند RNGCryptoServiceProvider برای تولید اعداد تصادفی و یا SHA256Managed (و تمام کلاسهای Managed_) برای هش کردن اطلاعات نیست. در ادامه این موارد را بررسی کرده و با معادلهای آنها در NET Core. آشنا خواهیم شد.
تغییرات الگوریتمهای هش کردن اطلاعات
با حذف و تغییرنام کلاسهایی مانند SHA256Managed (و تمام کلاسهای Managed_) در NET Core.، معادل کدهایی مانند:
به صورت ذیل درآمدهاست:
البته اگر از یک برنامهی ASP.NET Core استفاده میکنید، اسمبلیهای مرتبط آن به صورت پیش فرض به پروژه الحاق شدهاند. اما اگر میخواهید یک کتابخانهی جدید را ایجاد کنید، نیاز است وابستگی ذیل را نیز به فایل project.json آن اضافه نمائید:
به علاوه اگر نیاز به محاسبهی هش حاصل از جمع چندین byte array را دارید، در اینجا میتوان از الگوریتمهای IncrementalHash به صورت ذیل استفاده کرد:
این الگوریتمها شامل MD5، SHA1، SHA256، SHA384 و SHA512 میشوند.
تولید اعداد تصادفی Thread safe در NET Core.
روشهای زیادی برای تولید اعداد تصادفی در برنامههای دات نت وجود دارند؛ اما مشکل اکثر آنها این است که thread safe نیستند و نباید از آنها در برنامههای چند ریسمانی (مانند برنامههای وب)، به نحو متداولی استفاده کرد. در این بین تنها کلاسی که thread safe است، کلاس RNGCryptoServiceProvider میباشد؛ آن هم با یک شرط:
از کلاس آن باید تنها یک وهلهی static readonly در کل برنامه وجود داشته باشد (مطابق مستندات MSDN).
بنابراین اگر در کدهای خود چنین تعریفی را دارید:
اشتباه است و باید اصلاح شود.
در NET Core. این کلاس به طور کامل حذف شدهاست و معادل جدید آن کلاس RandomNumberGenerator است که به صورت ذیل قابل استفاده است (و در عمل تفاوتی بین کدهای آن با کدهای RNGCryptoServiceProvider نیست):
در اینجا نیز یک وهله از کلاس RandomNumberGenerator را ایجاد کردهایم، اما استاتیک نیست. علت اینجا است که چون برنامههای ASP.NET Core به همراه یک IoC Container توکار هستند، میتوان این کلاس را با طول عمر singleton معرفی کرد که همان کار را انجام میدهد:
و پس از این تنظیم، میتوان سرویس IRandomNumberProvider را در تمام قسمتهای برنامه، با کمک تزریق وابستگیهای آن در سازندهی کلاسها، استفاده کرد و نکتهی مهم آن thread safe بودن آن جهت کاربردهای چند ریسمانی است. بنابراین دیگر در برنامههای وب خود از new Random استفاده نکنید.
نیاز به الگوریتمهای رمزنگاری متقارن قوی و معادل بهتر آنها در ASP.NET Core
ASP.NET Core به همراه یکسری API جدید است به نام data protection APIs که روشهایی را برای پیاده سازی بهتر الگوریتمهای هش کردن اطلاعات و رمزنگاری اطلاعات، ارائه میدهند و برای مثال ASP.NET Core Identity و یا حتی Anti forgery token آن، در پشت صحنه دقیقا از همین API برای انجام کارهای رمزنگاری اطلاعات استفاده میکنند.
برای مثال اگر بخواهید کتابخانهای را طراحی کرده و در آن از الگوریتم AES استفاده نمائید، نیاز است تنظیم اضافهتری را جهت دریافت کلید عملیات نیز اضافه کنید. اما با استفاده از data protection APIs نیازی به اینکار نیست و مدیریت ایجاد، نگهداری و انقضای این کلید به صورت خودکار توسط سیستم data protection انجام میشود. کلیدهای این سیستم موقتی هستند و طول عمری محدود دارند. بنابراین باتوجه به این موضوع، روش مناسبی هستند برای تولید توکنهای Anti forgery و یا تولید محتوای رمزنگاری شدهی کوکیها. بنابراین نباید از آن جهت ذخیره سازی اطلاعات ماندگار در بانکهای اطلاعاتی استفاده کرد.
فعال سازی این سیستم نیازی به تنظیمات اضافهتری در ASP.NET Core ندارد و جزو پیش فرضهای آن است. در کدهای ذیل، نمونهای از استفادهی از این سیستم را ملاحظه میکنید:
کار با تزریق IDataProtectionProvider در سازندهی کلاس شروع میشود. سرویس آن به صورت پیش فرض توسط ASP.NET Core در اختیار برنامه قرار میگیرد و نیازی به تنظیمات اضافهتری ندارد. پس از آن باید یک محافظت کنندهی جدید را با فراخوانی متد CreateProtector آن ایجاد کرد و در آخر کار با آن به سادگی فراخوانی متدهای Unprotect و Protect است که ملاحظه میکنید.
پس از طراحی این سرویس جدید نیز میتوان وابستگیهای آنرا به نحو فوق به سیستم معرفی کرد و از سرویس IProtectionProvider آن در تمام قسمتهای برنامه (جهت کارهای کوتاه مدت رمزنگاری اطلاعات) استفاده نمود.
مستندات مفصل این API را در اینجا میتوانید مطالعه کنید.
معادل الگوریتم Rijndael در NET Core.
همانطور که عنوان شد، طول عمر کلیدهای data protection API محدود است و به همین جهت برای کارهایی چون تولید توکنها، رمزنگاری کوئری استرینگها و یا کوکیهای کوتاه مدت، بسیار مناسب است. اما اگر نیاز به ذخیره سازی طولانی مدت اطلاعات رمزنگاری شده وجود داشته باشد، یکی از الگوریتمهای مناسب اینکار، الگوریتم AES است.
الگوریتم Rijndael نگارش کامل دات نت، اینبار نام اصلی آن یا AES را در NET Core. پیدا کردهاست و نمونهای از نحوهی استفادهی از آن، جهت رمزنگاری و رمزگشایی اطلاعات، به صورت ذیل است:
همانطور که در کدهای فوق نیز مشخص است، این روش نیاز به قید صریح key و salt را دارد. اما روش استفادهی از data protection APIs مدیریت key و salt را خودکار کردهاست؛ آن هم با طول عمر کوتاه. در این حالت دیگر نیازی نیست تا جفت کلیدی را که احتمالا هیچگاه در طول عمر برنامه تغییری نمیکنند، از مصرف کنندهی کتابخانهی خود دریافت کنید و یا حتی نام خودتان را به عنوان کلید در کدها به صورت hard coded قرار دهید!
تغییرات الگوریتمهای هش کردن اطلاعات
با حذف و تغییرنام کلاسهایی مانند SHA256Managed (و تمام کلاسهای Managed_) در NET Core.، معادل کدهایی مانند:
using (var sha256 = new SHA256Managed()) { // Crypto code here... }
public static string GetHash(string text) { using (var sha256 = SHA256.Create()) { var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(text)); return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower(); } }
"dependencies": { "System.Security.Cryptography.Algorithms": "4.2.0" },
به علاوه اگر نیاز به محاسبهی هش حاصل از جمع چندین byte array را دارید، در اینجا میتوان از الگوریتمهای IncrementalHash به صورت ذیل استفاده کرد:
using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5)) { md5.AppendData(byteArray1, 0, byteArray1.Length); md5.AppendData(byteArray2, 0, byteArray2.Length); var hash = md5.GetHashAndReset(); }
تولید اعداد تصادفی Thread safe در NET Core.
روشهای زیادی برای تولید اعداد تصادفی در برنامههای دات نت وجود دارند؛ اما مشکل اکثر آنها این است که thread safe نیستند و نباید از آنها در برنامههای چند ریسمانی (مانند برنامههای وب)، به نحو متداولی استفاده کرد. در این بین تنها کلاسی که thread safe است، کلاس RNGCryptoServiceProvider میباشد؛ آن هم با یک شرط:
private static readonly RNGCryptoServiceProvider Rand = new RNGCryptoServiceProvider();
بنابراین اگر در کدهای خود چنین تعریفی را دارید:
var rand = new RNGCryptoServiceProvider();
در NET Core. این کلاس به طور کامل حذف شدهاست و معادل جدید آن کلاس RandomNumberGenerator است که به صورت ذیل قابل استفاده است (و در عمل تفاوتی بین کدهای آن با کدهای RNGCryptoServiceProvider نیست):
public interface IRandomNumberProvider { int Next(); int Next(int max); int Next(int min, int max); } public class RandomNumberProvider : IRandomNumberProvider { private readonly RandomNumberGenerator _rand = RandomNumberGenerator.Create(); public int Next() { var randb = new byte[4]; _rand.GetBytes(randb); var value = BitConverter.ToInt32(randb, 0); if (value < 0) value = -value; return value; } public int Next(int max) { var randb = new byte[4]; _rand.GetBytes(randb); var value = BitConverter.ToInt32(randb, 0); value = value % (max + 1); // % calculates remainder if (value < 0) value = -value; return value; } public int Next(int min, int max) { var value = Next(max - min) + min; return value; } }
public class Startup { public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton<IRandomNumberProvider, RandomNumberProvider>();
نیاز به الگوریتمهای رمزنگاری متقارن قوی و معادل بهتر آنها در ASP.NET Core
ASP.NET Core به همراه یکسری API جدید است به نام data protection APIs که روشهایی را برای پیاده سازی بهتر الگوریتمهای هش کردن اطلاعات و رمزنگاری اطلاعات، ارائه میدهند و برای مثال ASP.NET Core Identity و یا حتی Anti forgery token آن، در پشت صحنه دقیقا از همین API برای انجام کارهای رمزنگاری اطلاعات استفاده میکنند.
برای مثال اگر بخواهید کتابخانهای را طراحی کرده و در آن از الگوریتم AES استفاده نمائید، نیاز است تنظیم اضافهتری را جهت دریافت کلید عملیات نیز اضافه کنید. اما با استفاده از data protection APIs نیازی به اینکار نیست و مدیریت ایجاد، نگهداری و انقضای این کلید به صورت خودکار توسط سیستم data protection انجام میشود. کلیدهای این سیستم موقتی هستند و طول عمری محدود دارند. بنابراین باتوجه به این موضوع، روش مناسبی هستند برای تولید توکنهای Anti forgery و یا تولید محتوای رمزنگاری شدهی کوکیها. بنابراین نباید از آن جهت ذخیره سازی اطلاعات ماندگار در بانکهای اطلاعاتی استفاده کرد.
فعال سازی این سیستم نیازی به تنظیمات اضافهتری در ASP.NET Core ندارد و جزو پیش فرضهای آن است. در کدهای ذیل، نمونهای از استفادهی از این سیستم را ملاحظه میکنید:
public interface IProtectionProvider { string Decrypt(string inputText); string Encrypt(string inputText); } namespace Providers { public class ProtectionProvider : IProtectionProvider { private readonly IDataProtector _dataProtector; public ProtectionProvider(IDataProtectionProvider dataProtectionProvider) { _dataProtector = dataProtectionProvider.CreateProtector(typeof(ProtectionProvider).FullName); } public string Decrypt(string inputText) { var inputBytes = Convert.FromBase64String(inputText); var bytes = _dataProtector.Unprotect(inputBytes); return Encoding.UTF8.GetString(bytes); } public string Encrypt(string inputText) { var inputBytes = Encoding.UTF8.GetBytes(inputText); var bytes = _dataProtector.Protect(inputBytes); return Convert.ToBase64String(bytes); } } }
public class Startup { public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton<IProtectionProvider, ProtectionProvider>();
مستندات مفصل این API را در اینجا میتوانید مطالعه کنید.
معادل الگوریتم Rijndael در NET Core.
همانطور که عنوان شد، طول عمر کلیدهای data protection API محدود است و به همین جهت برای کارهایی چون تولید توکنها، رمزنگاری کوئری استرینگها و یا کوکیهای کوتاه مدت، بسیار مناسب است. اما اگر نیاز به ذخیره سازی طولانی مدت اطلاعات رمزنگاری شده وجود داشته باشد، یکی از الگوریتمهای مناسب اینکار، الگوریتم AES است.
الگوریتم Rijndael نگارش کامل دات نت، اینبار نام اصلی آن یا AES را در NET Core. پیدا کردهاست و نمونهای از نحوهی استفادهی از آن، جهت رمزنگاری و رمزگشایی اطلاعات، به صورت ذیل است:
public string Decrypt(string inputText, string key, string salt) { var inputBytes = Convert.FromBase64String(inputText); var pdb = new Rfc2898DeriveBytes(key, Encoding.UTF8.GetBytes(salt)); using (var ms = new MemoryStream()) { var alg = Aes.Create(); alg.Key = pdb.GetBytes(32); alg.IV = pdb.GetBytes(16); using (var cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(inputBytes, 0, inputBytes.Length); } return Encoding.UTF8.GetString(ms.ToArray()); } } public string Encrypt(string inputText, string key, string salt) { var inputBytes = Encoding.UTF8.GetBytes(inputText); var pdb = new Rfc2898DeriveBytes(key, Encoding.UTF8.GetBytes(salt)); using (var ms = new MemoryStream()) { var alg = Aes.Create(); alg.Key = pdb.GetBytes(32); alg.IV = pdb.GetBytes(16); using (var cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(inputBytes, 0, inputBytes.Length); } return Convert.ToBase64String(ms.ToArray()); } }
اگر یک پروژهی خالی ASP.NET Core Web Application را شروع کنید (با طی مراحل زیر جهت ایجاد یک پروژهی جدید):
تغییرات ساختاری ASP.NET Core 1.0، با نگارشهای قبلی ASP.NET، بسیار قابل ملاحظه هستند:
در اینجا نقش Solution همانند نگارشهای قبلی ویژوال استودیو است: ظرفی است برای ساماندهی موارد مورد نیاز جهت تشکیل یک برنامهی وب و شامل مواردی است مانند پروژهها، تنظیمات آنها و غیره. بنابراین هنوز در اینجا فایل sln. تشکیل میشود.
نقش فایل global.json
زمانیکه یک پروژهی جدید ASP.NET Core 1.0 را آغاز میکنیم، ساختار پوشههای آن به صورت زیر هستند:
در اینجا هنوز فایل sln. قابل مشاهده است. همچنین در اینجا فایل جدیدی به نام global.json نیز وجود دارد، با این محتوا:
شماره نگارش ذکر شدهی در اینجا را در قسمت قبل بررسی کردیم.
خاصیت projects در اینجا به صورت یک آرایه تعریف شدهاست و بیانگر محل واقع شدن پوشههای اصلی پروژهی جاری هستند. پوشهی src یا source را در تصویر فوق مشاهده میکنید و محلی است که سورسهای برنامه در آن قرار میگیرند. یک پوشهی test نیز در اینجا ذکر شدهاست و اگر در حین ایجاد پروژه، گزینهی ایجاد unit tests را هم انتخاب کرده باشید، این پوشهی مخصوص نیز ایجاد خواهد شد.
نکتهی مهم اینجا است، هرکدی که درون پوشههای ذکر شدهی در اینجا قرار نگیرد، قابلیت build را نخواهد داشت. به عبارتی این نسخهی از ASP.NET پوشهها را قسمتی از پروژه به حساب میآورد. در نگارشهای قبلی ASP.NET، مداخل تعریف فایلهای منتسب به هر پروژه، درون فایلی با پسوند csproj. قرار میگرفتند. معادل این فایل در اینجا اینبار پسوند xproj را دارد و اگر آنرا با یک ادیتور متنی باز کنید، فاقد تعاریف مداخل فایلهای پروژه است.
در این نگارش جدید اگر فایلی را به پوشهی src اضافه کنید یا حذف کنید، بلافاصله در solution explorer ظاهر و یا حذف خواهد شد.
یک آزمایش: به صورت معمول از طریق windows explorer به پوشهی src برنامه وارد شده و فایل پیش فرض Project_Readme.html را حذف کنید. سپس به solution explorer ویژوال استودیو دقت کنید. مشاهده خواهید کرد که این فایل، بلافاصله از آن حذف میشود. در ادامه به recycle bin ویندوز مراجعه کرده و این فایل حذف شده را restore کنید تا مجددا به پوشهی src برنامه اضافه شود. اینبار نیز افزوده شدن خودکار و بلافاصلهی این فایل را میتوان در solution explorer مشاهده کرد.
بنابراین ساختار مدیریت فایلهای این نگارش از ASP.NET در ویژوال استودیو، بسیار شبیه به ساختار مدیریت فایلهای VSCode شدهاست که آن نیز بر اساس پوشهها کار میکند و یک پوشه و تمام محتوای آنرا به صورت پیش فرض به عنوان یک پروژه میشناسد. به همین جهت دیگر فایل csproj ایی در اینجا وجود ندارد و file system همان project system است.
یک نکته: در اینجا مسیرهای مطلق را نیز میتوان ذکر کرد:
اما در مورد هر مسیری که ذکر میشود، NET Core. باید بتواند یک سطح پایینتر از پوشهی ذکر شده، فایل مهم project.json را پیدا کند؛ در غیراینصورت از آن صرفنظر خواهد شد. برای مثال برای مسیر نسبی src، مسیر src\MyProjectName\project.json را جستجو میکند و برای مسیر مطلق ذکر شده، این مسیر را c:\\sources\\Configuration\\src\\SomeName\\project.json
کامپایل خودکار پروژه در ASP.NET Core 1.0
علاوه بر تشخیص خودکار کم و زیاد شدن فایلهای سیستمی پروژه، بدون نیاز به Add new item کردن آنها در ویژوال استودیو، اگر سورسهای برنامه را نیز تغییر دهید، فایل سورس جدیدی را اضافه کنید و یا فایل سورس موجودی را حذف کنید، کل پروژه به صورت خودکار کامپایل میشود و نیازی نیست اینکار را به صورت دستی انجام دهید.
یک آزمایش: برنامه را از طریق منوی debug و گزینهی start without debugging اجرا کنید. اگر برنامه را در حالت معمول debug->start debugging اجرا کنید، حالت کامپایل خودکار را مشاهده نخواهید کرد. در اینجا (پس از start without debugging) یک چنین خروجی را مشاهده خواهید کرد:
این خروجی حاصل اجرای کدهای درون فایل Startup.cs برنامه است:
اکنون در همین حال که برنامه در حال اجرا است و هنوز IIS Express خاتمه نیافته است، از طریق windows explorer، به پوشهی src برنامه وارد شده و فایل Startup.cs را با notepad باز کنید. هدف این است که این فایل را در خارج از ویژوال استودیو ویرایش کنیم. اینبار سطر await دار را در notepad به نحو ذیل ویرایش کنید:
پس از آن اگر مرورگر را refresh کنید، بلافاصله خروجی جدید فوق را مشاهده خواهید کرد که بیانگر کامپایل خودکار پروژه در صورت تغییر فایلهای آن است.
این مساله قابلیت استفادهی از ASP.NET Core را در سایر ادیتورهای موجود، مانند VSCode سهولت میبخشد.
نقش فایل project.json
فایل جدید project.json مهمترین فایل تنظیمات یک پروژهی ASP.NET Core است و مهمترین قسمت آن، قسمت وابستگیهای آن است:
همانطور که در قسمت قبل نیز عنوان شد، در این نگارش از دات نت، تمام وابستگیهای پروژه از طریق نیوگت تامین میشوند و دیگر خبری از یک دات نت «بزرگ» که شامل تمام اجزای این مجموعهاست نیست. این مساله توزیع برنامه را سادهتر کرده و همچنین امکان به روز رسانی سریعتر این اجزا را توسط تیمهای مرتبط فراهم میکند؛ بدون اینکه نیازی باشد تا منتظر یک توزیع «بزرگ» دیگر ماند.
در نگارشهای قبلی ASP.NET، فایلی XML ایی به نام packages.config حاوی تعاریف مداخل بستههای نیوگت برنامه بود. این فایل در اینجا جزئی از محتوای فایل project.json در قسمت dependencies آن است.
با قسمت وابستگیهای این فایل، به دو طریق میتوان کار کرد:
الف) ویرایش مستقیم این فایل که به همراه intellisense نیز هست. با افزودن مداخل جدید به این فایل و ذخیره کردن آن، بلافاصله کار restore و دریافت و نصب آنها آغاز میشود:
ب) از طریق NuGet package manager
روش دیگر کار با وابستگیها، کلیک راست بر روی گره references و انتخاب گزینهی manage nuget packages است:
برای نمونه جهت نصب ASP.NET MVC 6 این مراحل باید طی شوند:
ابتدا برگهی browse را انتخاب کنید و سپس تیک مربوط به include prerelease را نیز انتخاب نمائید.
البته بستهی اصلی MVC در اینجا Microsoft.AspNetCore.Mvc نام دارد و نه MVC6.
اینبار بستههایی که restore میشوند، در مسیر اشتراکی C:\Users\user_name\.nuget\packages ذخیره خواهند شد.
یک نکتهی مهم:
قرار هست در نگارشهای پس از RTM، فایلهای project.json و xproj را جهت سازگاری با MSBuild، اندکی تغییر دهند (که این تغییرات به صورت خودکار توسط VS.NET انجام میشود). اطلاعات بیشتر
انتخاب فریم ورکهای مختلف در فایل project.json
در قسمت قبل عنوان شد که ASP.NET Core را میتوان هم برفراز NET Core. چندسکویی اجرا کرد و هم NET 4.6. مختص به ویندوز. این انتخابها در قسمت frameworks فایل project.json انجام میشوند:
در اینجا، netcoreapp1.0 به معنای برنامهای است که برفراز NET Core. اجرا میشود. نام پیشین آن dnxcore50 بود (اگر مقالات قدیمیتر پیش از RTM را مطالعه کنید).
در اینجا اگر علاقمند بودید که از دات نت کامل مخصوص ویندوز نیز استفاده کنید، میتوانید آنرا در لیست فریم ورکها اضافه نمائید (در این مثال، دات نت کامل 4.5.2 نیز ذکر شدهاست):
لیست کامل این اسامی را در مستندات NET Starndard میتوانید مطالعه کنید و خلاصهی آن به این صورت است:
- “netcoreapp1.0” برای معرفی و استفادهی از NET Core 1.0. بکار میرود.
- جهت معرفی فریم ورکهای کامل و ویندوزی دات نت، اسامی “net45”, “net451”, “net452”, “net46”, “net461” مجاز هستند.
- “portable-net45+win8” برای معرفی پروفایلهای PCL یا portable class libraries بکار میرود.
- “dotnet5.6”, “dnxcore50” برای معرفی نگارشهای پیش نمایش NET Core.، پیش از ارائهی نگارش RTM استفاده میشوند.
- “netstandard1.2”, “netstandard1.5” کار معرفی برنامههای NET Standard Platform. را انجام میدهند.
بر این مبنا، dotnet5.6 ذکر شدهی در قسمت تنظیمات نگارش RTM، به این معنا است که قادر به استفادهی از بستههای نیوگت و کتابخانههای تولید شدهی با نگارشهای RC نیز خواهید بود (هرچند برنامه از netcoreapp1.0 استفاده میکند).
یک مثال: قسمت فریم ورکهای فایل project.json را به نحو ذیل جهت معرفی دات نت 4.6.1 تغییر دهید:
لیست وابستگیهای خاص این فریم ورک در خاصیت dependencies آن قابل ذکر است.
در این حالت پس از ذخیرهی فایل و شروع خودکار بازیابی وابستگیها، با پیام خطای Package Microsoft.NETCore.App 1.0.0 is not compatible with net461 متوقف خواهید شد.
برای رفع این مشکل باید وابستگی Microsoft.NETCore.App را حذف کنید، چون با net461 سازگاری ندارد
فایل project.lock.json چیست؟
ذیل فایل project.json، فایل دیگری به نام project.lock.json نیز وجود دارد. اگر به محتوای آن دقت کنید، این فایل حاوی لیست دقیق بستههای نیوگت مورد استفادهی توسط برنامه است و الزاما با آنچیزی که در فایل project.json قید شده، یکی نیست. از این جهت که در فایل project.json، قید میشود netcoreapp1.0؛ ولی این netcoreapp1.0 دقیقا شامل چه بستههایی است؟ لیست کامل آنها را در این فایل میتوانید مشاهده کنید.
در ابتدای این فایل یک خاصیت locked نیز وجود دارد که مقدار پیش فرض آن false است. اگر به true تنظیم شود، در حین restore وابستگیهای برنامه، تنها از نگارشهای ذکر شدهی در این فایل استفاده میشود. از این جهت که در فایل project.json میتوان شماره نگارشها را با * نیز مشخص کرد؛ مثلا *.1.0.0
پوشهی جدید wwwroot و گره dependencies
یکی از پوشههای جدیدی که در ساختار پروژهی ASP.NET Core معرفی شدهاست، wwwroot نام دارد:
از دیدگاه هاستینگ برنامه، این پوشه، پوشهای است که در معرض دید عموم قرار میگیرد (وب روت). برای مثال فایلهای ایستای اسکریپت، CSS، تصاویر و غیره باید در این پوشه قرار گیرند تا توسط دنیای خارج قابل دسترسی و استفاده شوند. بنابراین سورس کدهای برنامه خارج از این پوشه قرار میگیرند.
گره dependencies که ذیل پوشهی wwwroot قرار گرفتهاست، جهت مدیریت این وابستگیهای سمت کلاینت برنامه است. در اینجا میتوان از NPM و یا Bower برای دریافت و به روز رسانی وابستگیهای اسکریپتی و شیوهنامههای برنامه کمک گرفت (علاوه بر نیوگت که بهتر است صرفا جهت دریافت وابستگیهای دات نتی استفاده شود).
یک مثال: فایل جدیدی را به نام bower.json به پروژهی جاری با این محتوا اضافه کنید:
این نامها استاندارد هستند. برای مثال اگر قصد استفادهی از npm مربوط به node.js را داشته باشید، نام این فایل packag.json است (با ساختار خاص خودش) و هر دوی اینها را نیز میتوانید با هم اضافه کنید و از این لحاظ محدودیتی وجود ندارد.
پس از اضافه شدن فایل bower.json، بلافاصله کار restore بستهها از اینترنت شروع میشود:
و یا با کلیک راست بر روی گره dependencies، گزینهی restore packages نیز وجود دارد.
فایلهای نهایی دریافت شده را در پوشهی bower_components خارج از wwwroot میتوانید مشاهده کنید.
در مورد نحوهی توزیع و دسترسی به فایلهای استاتیک یک برنامهی ASP.NET Core 1.0، نکات خاصی وجود دارند که در قسمتهای بعد، بررسی خواهند شد.
یک نکته: اگر خواستید نام پوشهی wwwroot را تغییر دهید، فایل جدیدی را به نام hosting.json با این محتوا به پروژه اضافه کنید:
در اینجا AppWebRoot نام دلخواه پوشهی جدیدی است که نیاز است به ریشهی پروژه اضافه نمائید تا بجای wwwroot پیش فرض استفاده شود.
نقطهی آغازین برنامه کجاست؟
اگر به فایل project.json دقت کنید، چنین تنظیمی در آن موجود است:
true بودن مقدار تولید entry point به استفادهی از فایلی به نام Program.cs بر میگردد؛ با این محتوا:
به این ترتیب، یک برنامهی ASP.NET Core، دقیقا همانند سایر برنامههای NET Core. رفتار میکند و در اساس یک برنامهی کنسول است.
این چند سطر، قسمتی از سورس کد ASP.NET Core 1.0 هستند. به این معنا که اگر مقدار خاصیت emitEntryPoint مساوی true بود، با این برنامه به شکل یک برنامهی کنسول رفتار کن و در غیر اینصورت یک Dynamically Linked Library خواهد بود.
در فایل Program.cs تنظیماتی را مشاهده میکنید، در مورد راه اندازی Kestler که وب سرور بسیار سریع و چندسکویی کار با برنامههای ASP.NET Core 1.0 است و قسمت مهم دیگر آن به استفادهی از کلاس Startup بر میگردد (()<UseStartup<Startup). این کلاس را در فایل جدید Startup.cs میتوانید ملاحظه کنید که کار تنظیمات آغازین برنامه را انجام میدهد. اگر پیشتر با OWIN، در نگارشهای قبلی ASP.NET کار کرده باشید، قسمتی از این فایل برای شما آشنا است:
در اینجا امکان دسترسی به تنظیمات برنامه، معرفی سرویسها، middlewareها و غیره وجود دارند که هرکدام، در قسمتهای آتی به تفصیل بررسی خواهند شد.
نقش فایل launchsetting.json
محتویات پیش فرض این فایل برای قالب empty پروژههای ASP.NET Core 1.0 به صورت ذیل است:
همانطور که مشاهده میکنید، در اینجا تنظیمات IIS Express قابل تغییر هستند. برای مثال port پیش فرض برنامه 7742 تنظیم شدهاست.
پروفایلهایی که در اینجا ذکر شدهاند، در تنظیمات پروژه نیز قابل مشاهده هستند: (کلیک راست بر روی پروژه و مشاهدهی properties آن و یا دوبار کلیک بر روی گره properties)
به علاوه امکان انتخاب این پروفایلها در زمان آغاز برنامه نیز وجود دارند:
نکتهی مهم تمام این موارد به قسمت environment variable قابل مشاهدهی در تصاویر فوق بر میگردد. این متغیر محیطی میتواند سه مقدار Development ، Staging و Production را داشته باشد و بر اساس این متغیر و مقدار آن، میتوان پروفایل جدیدی را تشکیل داد. زمانیکه برنامه بر اساس پروفایل خاصی بارگذاری میشود، اینکه چه متغیر محیطی انتخاب شدهاست، در کلاس Startup قابل استخراج و بررسی بوده و بر این اساس میتوان اقدامات خاصی را انجام داد. برای مثال تنظیمات خاصی را بارگذاری کرد و یا صفحات ویژهای را فعال و غیرفعال کرد (این موارد را در قسمتهای بعدی مرور میکنیم).
همچنین در اینجا به ازای هر پروفایل مختلف میتوان Url آغازین یا launch url و پورت آنرا مجزا درنظر گرفت و یا از وب سرور دیگری استفاده کرد.
.NET Core -> ASP.NET Core Web Application (.NET Core) -> Select `Empty` Template
در اینجا نقش Solution همانند نگارشهای قبلی ویژوال استودیو است: ظرفی است برای ساماندهی موارد مورد نیاز جهت تشکیل یک برنامهی وب و شامل مواردی است مانند پروژهها، تنظیمات آنها و غیره. بنابراین هنوز در اینجا فایل sln. تشکیل میشود.
نقش فایل global.json
زمانیکه یک پروژهی جدید ASP.NET Core 1.0 را آغاز میکنیم، ساختار پوشههای آن به صورت زیر هستند:
در اینجا هنوز فایل sln. قابل مشاهده است. همچنین در اینجا فایل جدیدی به نام global.json نیز وجود دارد، با این محتوا:
{ "projects": [ "src", "test" ], "sdk": { "version": "1.0.0-preview2-003121" } }
خاصیت projects در اینجا به صورت یک آرایه تعریف شدهاست و بیانگر محل واقع شدن پوشههای اصلی پروژهی جاری هستند. پوشهی src یا source را در تصویر فوق مشاهده میکنید و محلی است که سورسهای برنامه در آن قرار میگیرند. یک پوشهی test نیز در اینجا ذکر شدهاست و اگر در حین ایجاد پروژه، گزینهی ایجاد unit tests را هم انتخاب کرده باشید، این پوشهی مخصوص نیز ایجاد خواهد شد.
نکتهی مهم اینجا است، هرکدی که درون پوشههای ذکر شدهی در اینجا قرار نگیرد، قابلیت build را نخواهد داشت. به عبارتی این نسخهی از ASP.NET پوشهها را قسمتی از پروژه به حساب میآورد. در نگارشهای قبلی ASP.NET، مداخل تعریف فایلهای منتسب به هر پروژه، درون فایلی با پسوند csproj. قرار میگرفتند. معادل این فایل در اینجا اینبار پسوند xproj را دارد و اگر آنرا با یک ادیتور متنی باز کنید، فاقد تعاریف مداخل فایلهای پروژه است.
در این نگارش جدید اگر فایلی را به پوشهی src اضافه کنید یا حذف کنید، بلافاصله در solution explorer ظاهر و یا حذف خواهد شد.
یک آزمایش: به صورت معمول از طریق windows explorer به پوشهی src برنامه وارد شده و فایل پیش فرض Project_Readme.html را حذف کنید. سپس به solution explorer ویژوال استودیو دقت کنید. مشاهده خواهید کرد که این فایل، بلافاصله از آن حذف میشود. در ادامه به recycle bin ویندوز مراجعه کرده و این فایل حذف شده را restore کنید تا مجددا به پوشهی src برنامه اضافه شود. اینبار نیز افزوده شدن خودکار و بلافاصلهی این فایل را میتوان در solution explorer مشاهده کرد.
بنابراین ساختار مدیریت فایلهای این نگارش از ASP.NET در ویژوال استودیو، بسیار شبیه به ساختار مدیریت فایلهای VSCode شدهاست که آن نیز بر اساس پوشهها کار میکند و یک پوشه و تمام محتوای آنرا به صورت پیش فرض به عنوان یک پروژه میشناسد. به همین جهت دیگر فایل csproj ایی در اینجا وجود ندارد و file system همان project system است.
یک نکته: در اینجا مسیرهای مطلق را نیز میتوان ذکر کرد:
"projects": [ "src", "test", "c:\\sources\\Configuration\\src" ],
کامپایل خودکار پروژه در ASP.NET Core 1.0
علاوه بر تشخیص خودکار کم و زیاد شدن فایلهای سیستمی پروژه، بدون نیاز به Add new item کردن آنها در ویژوال استودیو، اگر سورسهای برنامه را نیز تغییر دهید، فایل سورس جدیدی را اضافه کنید و یا فایل سورس موجودی را حذف کنید، کل پروژه به صورت خودکار کامپایل میشود و نیازی نیست اینکار را به صورت دستی انجام دهید.
یک آزمایش: برنامه را از طریق منوی debug و گزینهی start without debugging اجرا کنید. اگر برنامه را در حالت معمول debug->start debugging اجرا کنید، حالت کامپایل خودکار را مشاهده نخواهید کرد. در اینجا (پس از start without debugging) یک چنین خروجی را مشاهده خواهید کرد:
این خروجی حاصل اجرای کدهای درون فایل Startup.cs برنامه است:
app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); });
await context.Response.WriteAsync("Hello DNT!");
این مساله قابلیت استفادهی از ASP.NET Core را در سایر ادیتورهای موجود، مانند VSCode سهولت میبخشد.
نقش فایل project.json
فایل جدید project.json مهمترین فایل تنظیمات یک پروژهی ASP.NET Core است و مهمترین قسمت آن، قسمت وابستگیهای آن است:
"dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0", "type": "platform" }, "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0" },
در نگارشهای قبلی ASP.NET، فایلی XML ایی به نام packages.config حاوی تعاریف مداخل بستههای نیوگت برنامه بود. این فایل در اینجا جزئی از محتوای فایل project.json در قسمت dependencies آن است.
با قسمت وابستگیهای این فایل، به دو طریق میتوان کار کرد:
الف) ویرایش مستقیم این فایل که به همراه intellisense نیز هست. با افزودن مداخل جدید به این فایل و ذخیره کردن آن، بلافاصله کار restore و دریافت و نصب آنها آغاز میشود:
ب) از طریق NuGet package manager
روش دیگر کار با وابستگیها، کلیک راست بر روی گره references و انتخاب گزینهی manage nuget packages است:
برای نمونه جهت نصب ASP.NET MVC 6 این مراحل باید طی شوند:
ابتدا برگهی browse را انتخاب کنید و سپس تیک مربوط به include prerelease را نیز انتخاب نمائید.
البته بستهی اصلی MVC در اینجا Microsoft.AspNetCore.Mvc نام دارد و نه MVC6.
اینبار بستههایی که restore میشوند، در مسیر اشتراکی C:\Users\user_name\.nuget\packages ذخیره خواهند شد.
یک نکتهی مهم:
قرار هست در نگارشهای پس از RTM، فایلهای project.json و xproj را جهت سازگاری با MSBuild، اندکی تغییر دهند (که این تغییرات به صورت خودکار توسط VS.NET انجام میشود). اطلاعات بیشتر
انتخاب فریم ورکهای مختلف در فایل project.json
در قسمت قبل عنوان شد که ASP.NET Core را میتوان هم برفراز NET Core. چندسکویی اجرا کرد و هم NET 4.6. مختص به ویندوز. این انتخابها در قسمت frameworks فایل project.json انجام میشوند:
"frameworks": { "netcoreapp1.0": { "imports": [ "dotnet5.6", "portable-net45+win8" ] } },
در اینجا اگر علاقمند بودید که از دات نت کامل مخصوص ویندوز نیز استفاده کنید، میتوانید آنرا در لیست فریم ورکها اضافه نمائید (در این مثال، دات نت کامل 4.5.2 نیز ذکر شدهاست):
"frameworks": { "netcoreapp1.0": { }, "net452": { } }
- “netcoreapp1.0” برای معرفی و استفادهی از NET Core 1.0. بکار میرود.
- جهت معرفی فریم ورکهای کامل و ویندوزی دات نت، اسامی “net45”, “net451”, “net452”, “net46”, “net461” مجاز هستند.
- “portable-net45+win8” برای معرفی پروفایلهای PCL یا portable class libraries بکار میرود.
- “dotnet5.6”, “dnxcore50” برای معرفی نگارشهای پیش نمایش NET Core.، پیش از ارائهی نگارش RTM استفاده میشوند.
- “netstandard1.2”, “netstandard1.5” کار معرفی برنامههای NET Standard Platform. را انجام میدهند.
بر این مبنا، dotnet5.6 ذکر شدهی در قسمت تنظیمات نگارش RTM، به این معنا است که قادر به استفادهی از بستههای نیوگت و کتابخانههای تولید شدهی با نگارشهای RC نیز خواهید بود (هرچند برنامه از netcoreapp1.0 استفاده میکند).
یک مثال: قسمت فریم ورکهای فایل project.json را به نحو ذیل جهت معرفی دات نت 4.6.1 تغییر دهید:
"frameworks": { "netcoreapp1.0": { "imports": [ "dotnet5.6", "portable-net45+win8" ] }, "net461": { "imports": [ "portable-net45+win8" ], "dependencies": { } } },
در این حالت پس از ذخیرهی فایل و شروع خودکار بازیابی وابستگیها، با پیام خطای Package Microsoft.NETCore.App 1.0.0 is not compatible with net461 متوقف خواهید شد.
برای رفع این مشکل باید وابستگی Microsoft.NETCore.App را حذف کنید، چون با net461 سازگاری ندارد
"dependencies": { //"Microsoft.NETCore.App": { // "version": "1.0.0", // "type": "platform" //},
فریم ورک دوم استفاده شده نیز در اینجا قابل مشاهده است.
فایل project.lock.json چیست؟
ذیل فایل project.json، فایل دیگری به نام project.lock.json نیز وجود دارد. اگر به محتوای آن دقت کنید، این فایل حاوی لیست دقیق بستههای نیوگت مورد استفادهی توسط برنامه است و الزاما با آنچیزی که در فایل project.json قید شده، یکی نیست. از این جهت که در فایل project.json، قید میشود netcoreapp1.0؛ ولی این netcoreapp1.0 دقیقا شامل چه بستههایی است؟ لیست کامل آنها را در این فایل میتوانید مشاهده کنید.
در ابتدای این فایل یک خاصیت locked نیز وجود دارد که مقدار پیش فرض آن false است. اگر به true تنظیم شود، در حین restore وابستگیهای برنامه، تنها از نگارشهای ذکر شدهی در این فایل استفاده میشود. از این جهت که در فایل project.json میتوان شماره نگارشها را با * نیز مشخص کرد؛ مثلا *.1.0.0
پوشهی جدید wwwroot و گره dependencies
یکی از پوشههای جدیدی که در ساختار پروژهی ASP.NET Core معرفی شدهاست، wwwroot نام دارد:
از دیدگاه هاستینگ برنامه، این پوشه، پوشهای است که در معرض دید عموم قرار میگیرد (وب روت). برای مثال فایلهای ایستای اسکریپت، CSS، تصاویر و غیره باید در این پوشه قرار گیرند تا توسط دنیای خارج قابل دسترسی و استفاده شوند. بنابراین سورس کدهای برنامه خارج از این پوشه قرار میگیرند.
گره dependencies که ذیل پوشهی wwwroot قرار گرفتهاست، جهت مدیریت این وابستگیهای سمت کلاینت برنامه است. در اینجا میتوان از NPM و یا Bower برای دریافت و به روز رسانی وابستگیهای اسکریپتی و شیوهنامههای برنامه کمک گرفت (علاوه بر نیوگت که بهتر است صرفا جهت دریافت وابستگیهای دات نتی استفاده شود).
یک مثال: فایل جدیدی را به نام bower.json به پروژهی جاری با این محتوا اضافه کنید:
{ "name": "asp.net", "private": true, "dependencies": { "bootstrap": "3.3.6", "jquery": "2.2.0", "jquery-validation": "1.14.0", "jquery-validation-unobtrusive": "3.2.6" } }
پس از اضافه شدن فایل bower.json، بلافاصله کار restore بستهها از اینترنت شروع میشود:
و یا با کلیک راست بر روی گره dependencies، گزینهی restore packages نیز وجود دارد.
فایلهای نهایی دریافت شده را در پوشهی bower_components خارج از wwwroot میتوانید مشاهده کنید.
در مورد نحوهی توزیع و دسترسی به فایلهای استاتیک یک برنامهی ASP.NET Core 1.0، نکات خاصی وجود دارند که در قسمتهای بعد، بررسی خواهند شد.
یک نکته: اگر خواستید نام پوشهی wwwroot را تغییر دهید، فایل جدیدی را به نام hosting.json با این محتوا به پروژه اضافه کنید:
{ "webroot":"AppWebRoot" }
نقطهی آغازین برنامه کجاست؟
اگر به فایل project.json دقت کنید، چنین تنظیمی در آن موجود است:
"buildOptions": { "emitEntryPoint": true, "preserveCompilationContext": true },
public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); }
var outputKind = compilerOptions.EmitEntryPoint.GetValueOrDefault() ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary;
در فایل Program.cs تنظیماتی را مشاهده میکنید، در مورد راه اندازی Kestler که وب سرور بسیار سریع و چندسکویی کار با برنامههای ASP.NET Core 1.0 است و قسمت مهم دیگر آن به استفادهی از کلاس Startup بر میگردد (()<UseStartup<Startup). این کلاس را در فایل جدید Startup.cs میتوانید ملاحظه کنید که کار تنظیمات آغازین برنامه را انجام میدهد. اگر پیشتر با OWIN، در نگارشهای قبلی ASP.NET کار کرده باشید، قسمتی از این فایل برای شما آشنا است:
public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } }
نقش فایل launchsetting.json
محتویات پیش فرض این فایل برای قالب empty پروژههای ASP.NET Core 1.0 به صورت ذیل است:
{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:7742/", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "Core1RtmEmptyTest": { "commandName": "Project", "launchBrowser": true, "launchUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
پروفایلهایی که در اینجا ذکر شدهاند، در تنظیمات پروژه نیز قابل مشاهده هستند: (کلیک راست بر روی پروژه و مشاهدهی properties آن و یا دوبار کلیک بر روی گره properties)
به علاوه امکان انتخاب این پروفایلها در زمان آغاز برنامه نیز وجود دارند:
نکتهی مهم تمام این موارد به قسمت environment variable قابل مشاهدهی در تصاویر فوق بر میگردد. این متغیر محیطی میتواند سه مقدار Development ، Staging و Production را داشته باشد و بر اساس این متغیر و مقدار آن، میتوان پروفایل جدیدی را تشکیل داد. زمانیکه برنامه بر اساس پروفایل خاصی بارگذاری میشود، اینکه چه متغیر محیطی انتخاب شدهاست، در کلاس Startup قابل استخراج و بررسی بوده و بر این اساس میتوان اقدامات خاصی را انجام داد. برای مثال تنظیمات خاصی را بارگذاری کرد و یا صفحات ویژهای را فعال و غیرفعال کرد (این موارد را در قسمتهای بعدی مرور میکنیم).
همچنین در اینجا به ازای هر پروفایل مختلف میتوان Url آغازین یا launch url و پورت آنرا مجزا درنظر گرفت و یا از وب سرور دیگری استفاده کرد.
نظرات نظرسنجیها
با توجه به آخرین نگارشهای موجود Angular و React، انتخاب شما برای انجام یک پروژه بزرگ کدام است؟
همه فریمورکهای ذکر شده جزو فریم ورکهای پر طرفدار هستند (البته عمر کم Blazor رو باید در نظر گرفت). دلیلم برای انتخاب Blazor، یکپارچه بودن با فریم ورک دات نت، امکان اشتراک کدهای برنامه با کدهای کلاینت و پشتیبانی و سرمایه گذاری خوب مایکروسافت هستش. بنده در تیم توسعه دو پروژه بزرگ بیمه ای بودم که کل پروژه با Angular کار شد. Angular فریم ورک کاملی هستش ولی با وجود استفاده از Type Script باز هم به علت ماهیت این زبان، نمیتونه ویژگیهای زبانی مثل #C رو داشته باشه. مثلاً شما یک کلاس تعریف میکنید برای نگاشت داده ای که از سرور دریافت میکنید. شما میتونید هر داده ای رو با هر شکلی و هر فیلدی از سمت سرور ارسال کنید در هر صورت اون داده به کلاس شما نگاشت میشه بدون هیچ خطایی. اگر دیباگ هم انجام بدید متوجه میشید اون فیلدهایی که هم نام بودن مپ شدن ولی کلاس شما عملاً یک آبجکت دیگه هست که حتی نمیتونید به اون آبجکت دسترسی داشته باشید چون داده ارسالی بدون توجه به نوع کلاس شما، نگاشت شده. (احتمالاً نتونستم دقیق توضیح بدم) این مشکل یکی از مشکلاتی هستش که توی پروژه بزرگ دردسر ساز میشه و دلیلش هم بحثی هستش که مربوط به زبان فریم ورکه. هر چند حجم بالای برنامه Blazor رو نمیشه فراموش کرد ولی بنظرم فعلاً برای برنامههای داخلی یک سازمان یا برنامه ای که برای کاربران، ارزش انتظار و دانلود برنامه وجود داره، انتخاب خیلی خوبی هست.
نظرات مطالب
Blazor 5x - قسمت 31 - احراز هویت و اعتبارسنجی کاربران Blazor WASM - بخش 1 - انجام تنظیمات اولیه
- از بین میرود. باید آنرا در local storage ذخیره کنید.
- بله. نمونه اینکار در پروژهی «پیاده سازی سیاستهای دسترسی پویای سمت سرور و کلاینت در برنامههای Blazor WASM» پس از لاگین انجام شده.
- خیر؛ نیازی نیست. توکنها به همراه امضای دیجیتال هستند و همچنین کلید رمزنگاری خصوصی آن بر روی سرور ذخیره میشود. کسی که توانسته در سمت کلاینت توکنی را تغییر دهد و آنرا از مرحلهی اعتبارسنجی خودکار سمت سرور رد کند (یعنی امضای دیجیتال تغییرات انجام شده را مجددا محاسبه و به توکن اعمال کرده)، به سرور شما و کلیدهای رمزنگاری خصوصی آن دسترسی دارد؛ یک چنین شخصی نیازی به دستکاری توکنی را ندارد، چون هم اکنون دسترسی او به سرور شما کامل است! محتوای یک JWT، هرچند قابل مشاهده و مطالعه است، اما امضاء شدهاست. یک چنین محتوای امضاء شدهای، در جاهای حساس دیگری هم کاربرد واقعی دارد: «تهیه XML امضاء شده جهت تولید مجوز استفاده از برنامه»
اشتراکها
VSCode برای توسعه دهندگان سیشارپ
VSCode for the C# Developer - Tim Corey - NDC London 2023
VSCode is a nimble editor that can do just about anything. In this session, we will set up and configure VSCode for use in C# development. Then we will use it to build, debug, and deploy a small .NET Core web application to Azure.
Along the way, we will go over a list of the top C#-focused plugins for VSCode. Whether you are just getting started with VSCode or you are used to VSCode but want to start building C# projects, this session will get you up to speed fast.
مسیرراهها