مطالب
چک لیست امنیتی پروژه های نرم افزاری تحت وب
 مقدمه:

امروزه یکی از بزرگترین دغدغه‌های فعالان حوزه آی تی، برقراری امنیت اطلاعات می‌باشد. با پدید آمدن بانک‌های داده‌ای آماری و مالی، حساسیت مسئله صد چندان می‌شود. در ادامه چک لیستی را ارائه می‌نمایم که با کمک آن می‌توانید تا حدود بسیار خوبی امنیت نرم افزار تحت وب خود را برقرار نمایید. در برخی از موارد مثال‌هایی از تکنولوژی مایکروسافت آورده شده است که این بدلیل تخصص نویسنده در تکنولوژی‌های مایکروسافت می‌باشد. در صورتیکه شما از تکنولوژی‌ها و زبان‌های سورس باز بهره می‌برید، می‌بایست معادل مورد ذکر شده را در زبان مورد استفاده خود بیابید .
ابتدا اجازه دهید مقداری با حملات آشنا شویم و سپس راه مقابله را در کنار هم بررسی نماییم.
 

مهمترین و خطرناک‌ترین حملات سطح وب :

حمله XSS

این نوع حملات بدین صورت است که هکر با استفاده از فرم‌های عمومی یا خصوصی (پنل‌های سایت) اقدام به ثبت کدهای مخرب جاوااسکریپت درون دیتابیس شما می‌نماید. همانطور که می‌دانید پایه اصلی سیستم‌های احراز هویت، ساخت فایل کوکی بر روی کامپیوتر کاربران می‌باشد. زمانی که مطلب ثبت شده‌ی هکر برای کاربران شما نمایش داده می‌شود، کدهای جاوا اسکریپت هکر روی مرورگر کاربر، اجرا شده و اطلاعات کوکی‌های کاربر به راحتی برای سایت هکر ارسال می‌شود (معمولا هکر یک صفحه روی وب می‌سازد تا بتواند اطلاعات دریافتی از کدهای جاوا اسکریپت خود را دریافت و در جایی ذخیره کند).
حال هکر به راحتی کوکی را بر روی مرورگر خودش تنظیم می‌کند و بعد وارد سایت شما می‌شود. سیستم شما او را با کاربر شما اشتباه می‌گیرد و به راحتی هکر به اطلاعات پنل کاربری کاربر(ان) شما دست پیدا می‌کند.
 

حمله SQL Injection

این حمله معروفترین حمله است که تقریبا با قدرت می‌توانم بگویم که درتکنولوژی ASP.Net با امکانات فوق العاده‌ای که بصورت توکار در دات نت در نظر گرفته شده است، بصورت کامل به فراموشی سپرده شده است. فقط 2 تا نکته‌ی ریز هست که باید در کدهایتان رعایت کنید و تمام.
این حمله بدین صورت است که هکر یک سری دستورات SQL را در کوئری استرینگ، به صفحات تزریق می‌کند و بدین صورت می‌تواند در کدهای کوئری TSQL شما اختلال ایجاد کند و اطلاعات جداول شما را بدست بیاورد. در این نوع حمله، هکر از طریق باگ سطح کد نویسی کدهای نرم افزار، به دیتابیس حمله می‌کند و اطلاعاتی مثل نام کاربری و کلمه‌ی عبور ادمین یا کاربران را می‌دزد و بعد می‌رود داخل پنل و خرابکاری می‌کند.
 

حمله CSRF

این حمله یکی از جالب‌ترین و جذاب‌ترین نوع حملات است که هوش بالای دوستان هکر را نشون می‌دهد. عبارت CSRF مخفف Cross Site Request Forgery است (احتمالا دوستان ام وی سی کار، این عبارت برایشان آشناست).
در این نوع حمله هکر یک فایل برای کاربر شما از طریق ایمیل یا روش‌های دیگر ارسال می‌کند و کاربر را به این سمت سوق می‌دهد که فایل را باز کند. کاربر یک فایل به ظاهر معمولی مثل عکس یا ... را می‌بیند و فایل را باز می‌کند. وقتی فایل باز می‌شود دیتای خاصی دیده نمی‌شود و گاهی هم اروری مبنی بر ناقص بودن فایل یا ... به کاربر نمایش داده می‌شود و کاربر فکر می‌کند که فایل، ناقص برای ارسال شده ...
اما در حقیقت با کلیک بر روی فایل و باز کردن آن یک درخواست POST از کامپیوتر کاربر برای سایت شما ارسال می‌شود و در صورتیکه کاربر در آن زمان در سایت شما لاگین باشد، سایت درخواست را با روی باز می‌پذیرد و درخواست را اجرا می‌کند. بدین صورت هکر می‌تواند درخواست‌هایی را به سرویس‌های سایت شما که مثلا برای حذف یک سری داده است، ارسال کند و اطلاعات کاربر را حذف کند.
 

حمله Brute Force

در این حمله، هکر از یک سری برنامه برای ارسال درخواست‌های مکرر به فرم‌های سایت شما استفاده می‌کند و بدین صورت فرم‌های عمومی سایت شما مورد حجوم انبوهی از درخواست‌ها قرار می‌گیرد که این امر در بهترین حالت موجب ثبت کلی دیتای اسپم در دیتابیس شما و در بدترین حالت موجب داون شدن سایت شما می‌شود.
 

حمله DDOS

این نوع حمله مانند حمله Brute Force است؛ با این تفاوت که درخواست به همه‌ی صفحات شما ارسال می‌شود و معمولا درخواست‌ها از چندین سرور مختلف برای سایت شما ارسال می‌شوند و حجم درخواست‌ها به قدری زیاد است که عملا سرور شما هنگ می‌کند و کاملا از دسترس خارج می‌شود. این نوع حمله در سطح کد راه حل زیادی ندارد و در سطح سرور و فایروال باید حل شود و حل آن هم بدین صورت است که درخواست‌های بیش از حد طبیعی از یک آی پی خاص تشخیص داده شده و به سرعت، آی پی بلاک می‌شود و از آن به بعد درخواست‌های آن آی پی در فایروال از بین می‌رود و دیگه به سرور نمیرسد.


حمله SHELL

شل فایلی است خطرناک که اگر بر روی سرور سایت شما آپلود و اجرا شود، هکر از طریق آن دسترسی کاملی به کل سرور سایت شما خواهد داشت. فایل‌های دیگری با نام بک‌دور [1] نیز وجود دارند که نویسنده تمایل دارد آنها را نیز از نوع حمله SHELL معرفی نماید. این نوع از فایل‌ها به مراتب بسیار خطرناک‌تر از فایل‌های شل می‌باشند؛ تا جایی که ممکن است سال‌ها هکر به سروی دسترسی داشته باشد و مدیر سرور کاملا از آن بی خبر باشد. اینجاست که باید شدیدا مراقب فایل‌هایی که روی سایت شما آپلود می‌شوند باشید. نویسنده به تمامی خوانندگان پیشنهاد می‌نماید، در صورتیکه نرم افزار حساسی دارند، حتما از سرور اختصاصی استفاده نمایند؛ چرا که در هاست‌های اشتراکی که در آنها فضا و امکانات یک سرور بصورت اشتراکی در اختیار چندین سایت قرار می‌گیرد، وجود باگ امنیتی در سایر سایت‌های موجود بر روی سرور اشتراکی می‌تواند امنیت سایت شما را نیز به مخاطره بیاندازد. نویسنده تهیه‌ی سرور اختصاصی را شدیدا به توسعه دهندگان سایت‌های دارای تراکنش‌های بانکی بالا (داخلی یا خارجی) پیشنهاد می‌نماید. زیرا درگاه تراکنش‌های بانکی بر روی آی پی هاست شما قفل می‌شوند و در صورتیکه سرور بصورت اختصاصی تهیه شده باشد، آی پی سرور شما فقط و فقط در اختیار شماست و هکر نمی‌تواند با تهیه هاستی بر روی سرور اشتراکی شما، به راحتی آی پی قفل شده در درگاه بانکی شما را در اختیار داشته باشد. بدیهی است تنها در اختیار داشتن آی پی سرور شما جهت انجام خرابکاری در درگاه بانکی شما کافی نیست. ولی به نظر نویسنده این مورد در بدترین حالت ممکن 30% کار هکر می‌باشد. البته بحث حمله شل به سطح مهارت متخصصان سرورها نیز بستگی دارد. نویسنده اظهار می‌دارد اطلاعات دقیقی از تنظیماتی که بتواند جلوی اجرای انواع شل و یا جلوی دسترسی فایل‌های شل را بگیرد، ندارد. بنابراین از متخصصان این حوزه دعویت می‌نماید اطلاعاتی درباره این موضوع ارائه نمایند.
 

حمله SNIFF

در این نوع حملات، هکر پکت‌های رد و بدل شده‌ی بین کاربران و سرور شما را شنود می‌نماید و به راحتی می‌تواند اطلاعات مهمی مثل نام کاربری و رمز عبور کاربران شما را بدست آورد.



چک لیست امنیتی پروژه‌های نرم افزاری تحت وب

- بررسی کامل ورودی‌های دریافتی از فرم‌های سایت؛ هم در سمت کلاینت و هم در سطح سرور .
- در تکنولوژی دات نت به منظور تمیز سازی ورودی‌ها و حذف تگهای خطرناکی همچون تگ script، کتابخانه‌ای با نام Microsoft.Security.Application وجود دارد. کتابخانه‌های سورس باز دیگری نیز وجود دارند که نمونه آن کتابخانه AntiXss [2] سایت نوگت [3] می‌باشد.
- بررسی کامل ورودی‌های دریافتی از کوئری استرینگ‌های [4] سایت. اگر از ASP.Net MVC استفاده می‌نمایید، تا حدی زیادی نیاز به نگرانی نخواهد داشت، زیرا تبدیلات [5] در سیستم Model Binding انجام می‌پذیرد و این موضوع تا حد زیادی شما را در برابر حملات SQL Injection مقاوم می‌نماید.
- حتما در فرم‌های عمومی سایتتان از تصویر کپچا با امنیت بالا استفاده نمایید. این موضوع جهت شناخت روبات‌ها از انسان‌ها می‌باشد و شما را در برابر حملات Brute Force مقاوم می‌نماید.
-  حتما سیستم شخصی سازی صفحات ارور را فعال نمایید و از نمایش صفحات ارور حاوی اطلاعات مهمی مانند صفحات ارور ASP.Net جلوگیری نمایید. این موضوع بسیار حساس می‌باشد و می‌تواند نقاط ضعف نرم افزار شما را برای هکر نمایان کند. حتی ممکن است اطلاعات حساسی مانند نام بانک اطلاعاتی، نام کاربری اتصال به بانک اطلاعاتی و نام جداول بانک اطلاعاتی شما را در اختیار هکر قرار دهد.
- استفاده از ORM ها یا استفاده از پروسیجرهای پارامتریک. این موضوع کاملا شما را در برابر حملات SQL Injection مقاوم می‌نماید. کما اینکه ORM ها، سطحی از کش را بصورت توکار دارا می‌باشند و این موضوع در سرعت دستیابی به داده‌ها نیز بسیار تاثیر گذار است. از طرف دیگر بانک اطلاعاتی SQL نیز امکانات توکاری جهت کش نمودن پرس و جو‌های [6] پارامتریک دارد.
- لاگ کردن ارورهای سطح کد و سطح روتینگ [7] . یکی از مهمترین خصیصه‌های پروژه‌های با کیفیت، لاگ شدن خطاهای سطح کد می‌باشد. این امر شما را با نقاط حساس و ضعف‌های نرم افزار آگاه می‌سازد و به شما اجازه می‌دهد به سرعت در جهت رفع آنها اقدام نمایید. لاگ نمودن خطاهای سطح روتینگ شما را از فعالیت‌های هکر‌ها جهت یافتن صفحات لاگین و صفحات مدیریتی پنل مدیریتی سایت اگاه می‌نماید، همچنین شما را از حملات SQL Injection نیز آگاه می‌نماید.
- جلوگیری از ایندکس شدن صفحات لاگین پنل مدیریت سایت در موتورهای جستجو. بخش مهمی از عملیات هکر ها، قرار دادن روبات‌های تشخیص رمز بر روی صفحات لاگین می‌باشد که به نوعی می‌توان این نوع حملات را در دسته حملات Brute Force قرار داد. موتورهای جستجو یکی از ابزارهای مهم هکرها می‌باشد. عملیات هایی مانند یافتن صفحات لاگین پنل مدیریتی یکی از کاربردهای موتورهای جستجو برای هکرها می‌باشد.
- لاگ کردن ورود و خروج افراد به همراه تاریخ، زمان، آی پی افراد و وضعیت لاگین. با کمک این موضوع شما می‌توانید ورود و خروج کاربران نرم افزار خود را کنترل نمایید و موارد غیر طبیعی و مشکوک را در سریعترین زمان مورد بررسی قرار دهید.
- استفاده از روال‌های استاندارد جهت بخش "فراموشی کلمه عبور". همیشه از استاندارهای نرم افزارهای بزرگ پیروی نمایید. بدیهی است استاندارهای استفاده شده در این نرم افزارها بارها و بارها تست شده و سپس بعنوان یک روال استاندارد در همه‌ی نرم افزارهای بزرگ بکار گرفته شده است. استاندارد جهانی بخش "فراموشی کلمه عبور" که در اغلب نرم افزارهای معروف جهان بکار گرفته شده است، عبارت است از دریافت آدرس ایمیل کاربر، احراز هویت ایمیل وارد شده، ارسال یک نامه‌ی الکترونیکی [8] حاوی نام کاربری و لینک تنظیم کلمه عبور جدید به ایمیل کاربر. بهتر است لینک ارسال شده به ایمیل کاربر بصورت یکبار مصرف باشد. کاربر پس از کلیک بر روی لینک تنظیم کلمه عبور جدید، وارد یکی از صفحات سایت شده و می‌تواند کلمه‌ی عبور جدیدی را برای خود ثبت نماید. در پایان، کاربر به صفحه‌ی ورود سایت هدایت شده و پیامی مبنی بر موفقیت آمیز بودن عملیات تغییر کلمه‌ی عبور به او نمایش داده می‌شود. البته روال ذکر شده حداقل رول استانداردی می‌باشد و می‌توان در کنار آن از روال‌های تکمیل کننده‌ای مانند پرسش‌های امنیتی و غیره نیز استفاده نمود.
- قراردادن امکاناتی جهت بلاک نمودن آی پی‌ها و غیر فعال نمودن حساب کاربری اعضای سایت. در نرم افزار باید این امکان وجود داشته باشد که آی پی هایی که بصورت غیر طبیعی در سایت فعالیت می‌نمایند و یا مکررا اقدام به ورود به پنل مدیریتی و پنل کاربران می‌نمایند را بلاک نماییم. همچنین در صورت تخلف کاربران باید بتوان حساب کاربری کاربر خاطی را مسدود نمود. این موضوع می‌تواند بسته به اندازه پروژه و یا سلیقه تیم توسعه بصورت خودکار، دستی و یا هر دو روش در نرم افزار در تعبیه شود.
- امن سازی سرویس‌های ای جکس و چک کردن ای جکس بودن درخواست ها. حتما جلوی اجرای سرویس‌های درون نرم افزاری از بیرون از نرم افزار را بگیرید. سرویس‌های ای جکس یکی از این نوع سرویس‌ها می‌باشند که در نرم افزار‌ها جهت استفاده‌های داخلی در نظر گرفته می‌شوند. در این نوع سرویس‌ها حتما نوع درخواست را بررسی نمایید و از پاسخگویی سرویس‌ها به درخواست‌های غیر ای جکسی جلوگیری نمایید. در ASP.Net MVC این امر توسط متد Request.IsAjaxRequest انجام می‌پذیرد .
- محدود کردن سرویس‌های حساس به درخواست‌های POST. حتما از دسترسی به سرویس هایی از نوع Insert,Update و Delete از طریق فعل GET جلوگیری نمایید. در ASP.Net MVC این سرویس‌ها را به فعل POST محدود نموده و در ASP.Net Web API این سرویس‌ها را به افعال POST,PUT و DELETE محدود نمایید.
- عدم استفاده از آی دی در پنل‌های کاربران بالاخص در آدرس صفحات (کوئری استرینگ) و استفاده از کد غیر قابل پیش بینی مثل GUID به جای آن. حتی الامکان بررسی مالکیت داده‌ها در همه بخش‌های پنل‌های کاربری سایت را جهت محکم کاری بیشتر انجام دهید تا خدای نکرده کاربر با تغییر اطلاعات کوئری استرینگ صفحات نتوانند به داده‌های یک کاربر دیگه دسترسی داشته باشند.
- حتی الامکان پنل مدیران را از کاربران بصورت فیزیکی جدا نمایید. این مورد جهت جلوگیری از خطاهایی است که ممکن است توسط توسعه دهنده در سطح سیستم مدیریت نقش رخ دهد و موجب دسترسی داشتن کاربران به بخش هایی از پنل مدیریتی شود.
- استفاده از الگوریتم‌های کدگذاری ترکیبی و کد کردن اطلاعات حساس قبل از ذخیره سازی در بانک اطلاعاتی. اطلاعات حساسی مانند کلمات عبور را حتما توسط چند الگوریتم کدگذاری، کدگذاری نمایید و سپس درون بانک اطلاعاتی ذخیره نمایید.
- تنظیمات حساس نرم افزار را درون فایل web.config قرار دهید و حتی الامکان آنها را نیز کدگذاری نمایید. بصورتی که اطلاعات قابلیت دیکد شدن را داشته باشند.
- ساخت پروژه بصورت چند لایه. این موضوع جهت جلوگیری از دستیابی هکر به ساختار لایه‌های پروژه‌های شما می‌باشد. به بیان دیگر اگر نهایتا هکر بتواند به اطلاعات FTP هاست شما دست یابد، استفاده از تکنولوژی چند لایه در بدترین حالت هکر را از دستیابی به اطاعات لایه‌های زیرین نرم افزار باز می‌دارد. البته این کار برای هکر‌ها غیر ممکن نیست، اما بسیار سخت و زمان بر می‌باشد.
- اشتراک گذاری اینترفیس در سرویس‌های خارج برنامه ای و عدم اشتراک گذاری کلاس اصلی. این موضوع از دستیابی هکر به بدنه سرویس‌ها و پیاده سازی‌های آنها جلوگیری می‌نماید.
- استفاده از تکنیک‌های مقابله با CSRF در همه سرویس‌های POST. در ASP.NET MVC اتریبیوتی با نام AntiForgery جهت مقاوم سازی سرویس‌ها از حملات CSRF وجود دارد. مکانیزم بدین صورت است که در تمامی فرم‌های سایت یک کد منحصر به فرد تولید می‌گردد که همراه درخواست GET به کامپیوتر کاربر ارسال می‌شود و در هنگام ارسال درخواست POST به سرور، صحت کد مورد نظر بررسی شده و در صورت صحت، اجازه‌ی اجرای سرویس به درخواست داده می‌شود. بدین صورت وقتی کاربر سایت شما فایل آلوده‌ای را باز می‌نماید، در خواست ارسالی هکر که توسط فایل باز شده، به سرور سایت ما ارسال می‌گردد، فاقد کد منحصر به فرد بوده و از اجرای سرویس جلو گیری می‌شود.
- استفاده از سیستم‌های مدیریت نقش امن مانند IDENTITY در ASP.Net MVC و یا استفاده از امکانات توکار دات نت در سیستم‌های مدیریت نقش شخصی سازی شده [9] . بدیهی است امنیت این سیستم‌ها بارها و بارها تست شده است.
- بررسی فرمت و پسوند فایل‌های آپلود شده. توجه نمایید که بررسی پسوند فایل‌ها کافی نبوده و فرمت فایل‌ها نیز می‌بایست بررسی شود. حتی نویسنده پیشنهاد می‌نماید فایل‌ها را به نوع‌های مرتبطشان تبدیل [10] نمایید. در حوزه هک بایند نمودن انواع ویروس، تروجان، شل و بک دور [11] به فایل‌های تصویری و متنی یک امر بسیار رایج است. بنابراین حساسیت زیادی روی این موضوع قرار دهید. نویسنده توصیه می‌نماید کتابخانه‌های کاملی برای این موضوع تدارک ببینید تا در تمامی پروژه‌ها نیاز به ایجاد مجدد آنها نداشته باشید و سعی نمایید در هر پروژه این کتابخانه‌ها را تکمیل‌تر و بهتر نمایید.
- تنظیم IIS  جهت جلوگیری از اجرای فایل‌های اجرایی در مسیر آپلود فایل‌ها. شاید جمله بیان شده به نظر ترسناک و یا سخت برسد، اما این کار با نوشتن چند تگ ساده در فایل Web.Config به راحتی قابل انجام است و نیاز به هیچ نوع کدنویسی ندارد.
- آپلود فایل‌ها در پوشه App_Data و دسترسی به فایل‌ها از طریق سرویس‌های خود شما. پوشه App_Data پوشه‌ای امن است و دسترسی مستقیم از طریق آدرس بار مرورگر به فایل‌های درون آن توسط IIS داده نمی‌شود و افراد فقط از طریق سرویس‌های خود شما می‌توانند به فایل‌های داخل این پوشه دسترسی داشته باشند. بدین صورت در سرویس‌های خود می‌توانید با تبدیل نمودن [12] فایل‌ها به نوع خودشان (تصویر. پی دی اف یا ...) هکر را نا امید نمایید. این موضوع شما را در مقابل حملات SHELL مقاوم می‌نماید.
- استفاده از تکنیک‌های لاگین چند سطحی برای پنل ادمین. در این روش شما حتی با داشتن نام کاربری و کلمه‌ی عبور ادمین، قادر نخواهید بود وارد پنل ادمین شوید. نویسنده ابزار می‌دارد که این روش، یک روش ابداعی می‌باشد که از ترکیبی از احرا هویت ساده توسط نام کاربری و کلمه‌ی عبور به همراه تکنیک‌های احراز هویت ایمیل و موبایل مدیریت سایت می‌باشد.
- استفاده از SSL بسیار اهمیت دارد. بالاخص اگر نرم افزار شما Service Oriented باشد و نرم افزار شما سرویس هایی جهت اتصال به اپلیکیشن‌های خارجی مثل اپلیکیشن اندروید دارد. این مورد در صفحات لاگین نیز بسیار مهم است و موجب می‌شود نام کاربری و کلمه عبور کاربران شما بصورت هش شده بین کامپیوتر کاربر و سرور شما رد و بدل شود و عملا شنود پکت‌ها فایده ای برای هکر نخواهد داشت، زیرا داده‌ها توسط الگوریتم‌های امنیتی که بین سرور و مرورگر کاربران توافق می‌شود کدگذاری شده و سپس رد و بدل می‌شوند.



[1] Back Door
[2] https://www.nuget.org/packages/AntiXss/
[3] www. Nuget.org
[4] Query String
[5] Casting
[6] Procedure
[7] Routing
[8] Email
[9] Custom Role Provider
[10] Cast
[11] Back Door
[12] Cast
نظرات اشتراک‌ها
ایجاد یک موتور جستجوی سفارشی جهت search bar فایرفاکس
خیلی مفید هست این لیست
فقط میشه بگین این فایرفاکس رو فقط برا توسعه وب استفاده میکتید یا برا وب گردی هم از همین استفاده میکنید. آخه هیچ افزونه ای مثلا برا مدیریت یوزر پس سایت‌ها یا واسه بوکمارک و read later  و از موارد نیست توش آخه
ولی خیلی افزونه‌های کاربردی هستن خداییش
100 تا تشکر از لیستتون
مطالب
آموزش MEF#1
Managed Extensibility Framework یا MEF کامپوننتی از Framework 4 است که برای ایجاد برنامه‌های توسعه پذیر (Extensible) با حجم کم کد استفاده میشه.این تکنولوژی به برنامه نویسان این امکان رو میده که توسعه‌های (Extension) برنامه رو بدون پیکربندی استفاده کنند. همچنین به توسعه دهندگان این اجازه رو می‌ده که به آسانی کدها رو کپسوله کنند .
MEF به عنوان بخشی از 4 NET. و Silverlight 4 معرفی شد. MEF یک راه حل ساده برای مشکل توسعه در حال اجرای برنامه‌ها ارائه می‌کند.تا قبل از این تکنولوژی ، هر برنامه‌ای که می‌خواست یک مدل Plugin را پشتیبانی کنه لازم بود که خودش زیر ساخت‌ها را از ابتدا ایجاد کنه . این Plugin‌ها اغلب برای برنامه‌های خاصی بودند و نمی‌توانستند در پیاده سازی‌های چندگانه دوباره استفاده شوند. ولی MEF در راستای حل این مشکلات ، روش استانداردی رو برای میزبانی برنامه‌های کاربردی پیاده کرده است. 
برای فهم بهتر مفاهیم یک مثال ساده رو با MEF پیاده سازی می‌کنم.
ابتدا یک پروژه از نوع Console Application ایجاد کنید . بعد با استفاده از Add Reference یک ارجاع به System.ComponentModel.Composition بدید. سپس یک Interface به نام IViewModel را به صورت زیر ایجاد کنید:
public interface IViewModel
    {
        string Name { get; set; }
    }

یک خاصیت به نام Name برای دسترسی به نام ViewModel ایجاد می‌کنیم.
سپس 2 تا ViewModel دیگه ایجاد می‌کنیم که IViewModel را پیاده سازی کنند. به صورت زیر:
ViewModelFirst:
[Export( typeof( IViewModel ) )]
    public class ViewModelFirst : IViewModel
    {
        public ViewModelFirst()
        {
            this.Name = "ViewModelFirst";
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _name;
    }


ViewModelSecond:
[Export( typeof( IViewModel ) )]
    public class ViewModelSecond : IViewModel
    {
        public ViewModelSecond()
        {
            this.Name = "ViewModelSecond";
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _name;
    }


Export Attribute استفاده شده در بالای کلاس‌های ViewModel به این معنی است که این کلاس‌ها اینترفیس IViewModel رو Export کردند تا در جای مناسب بتونیم این ViewModel ‌ها Import کنیم.(Import , Export از مفاهیم اصلی در MEF هستند)
حالا نوبت به پیاده سازی کلاس Plugin می‌رسه.
public class PluginManager
    {
        public PluginManager()
        {

        }

        public IList<IViewModel> ViewModels
        {
            get
            {
                return _viewModels;
            }
            private set
            {
                _viewModels = value;
            }
        }

        [ImportMany( typeof( IViewModel ) )]
        private IList<IViewModel> _viewModels = new List<IViewModel>();

        public void SetupManager()
        {
            AggregateCatalog aggregateCatalog = new AggregateCatalog();

            CompositionContainer container = new CompositionContainer( aggregateCatalog );

            CompositionBatch batch = new CompositionBatch();

            batch.AddPart( this );

            aggregateCatalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );           

            container.Compose( batch );
        }

کلاس PluginManager برای شناسایی و استفاده از کلاس هایی که صفت‌های Export رو دارند نوشته شده(دقیقا شبیه یک UnityContainer در Microsoft Unity Application Block یا IKernel در Ninject) عمل می‌کنه با این تفاوت که نیازی به Register با Bind کردن ندارند)
ابتدا بک لیست از کلاس هایی که IViewModel رو Export کردند داریم.
بعد در متد SetupManager ابتدا یک AggregateCatalog نیاز داریم تا بتونیم Composition Part‌ها رو بهش اضافه کنیم. به کد زیر توجه کنید:
 aggregateCatalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );

تو این قطعه کد من یک Assembly Catalog رو که به Assembly جاری برنامه اشاره می‌کنه به AggregateCatalog اضافه کردم.
متد (batch.AddPart(this در واقع به این معنی است که به MEF گفته می‌شود این کلاس ممکن است شامل Export هایی باشد که به یک یا چند Import وابستگی دارند.
متد (AddExport(this در CompositionBatch به این معنی است که این کلاس ممکن است شامل Exportهایی باشد که به Import وابستگی ندارند.
حالا برای مشاهده نتایج کد زیر را در کلاس Program اضافه می‌کنیم:
static void Main( string[] args )
        {
            PluginManager plugin = new PluginManager();

            Console.WriteLine( string.Format( "Number Of ViewModels Before Plugin Setup Is [ {0} ]", plugin.ViewModels.Count ) );

            Console.WriteLine( Environment.NewLine );

            plugin.SetupManager();

            Console.WriteLine( string.Format( "Number Of ViewModels After Plugin Setup Is [ {0} ]", plugin.ViewModels.Count ) );

            Console.ReadLine();
        }

در کلاس بالا ابتدا تعداد کلاس‌های موجود در لیست ViewModels رو قبل از Setup کردن Plugin نمایش داده سپس بعد از Setup  کردن Plugin  دوباره تعداد کلاس‌های موجود در لیست ViewModel رو مشاهده می‌کنیم.که خروجی به شکل زیر تولید خواهد شد.


متد SetupManager در کلاس Plugin (با توجه به AggregateCatalog) که در این برنامه فقط Assembly  جاری رو بهش اضافه کردیم تمام کلاس هایی رو که نوع IViewModel رو Export کردند پیدا کرده و در لیست اضافه می‌کنه(این کار رو با توجه به ImportMany Attribute) انجام میده. در پست‌های بعدی روش استفاده از MEF رو در Prism یا WAF توضیح می‌دم.
مطالب
لینک‌های هفته‌ی آخر اسفند

وبلاگ‌ها ، سایت‌ها و مقالات ایرانی (داخل و خارج از ایران)

امنیت

Visual Studio

ASP. Net

طراحی و توسعه وب

PHP

اس‌کیوال سرور

سی شارپ

VB

عمومی دات نت

جاوا

ویندوز

مسایل اجتماعی و انسانی برنامه نویسی

SVN

متفرقه

مطالب
معرفی ASP.NET Identity

سیستم ASP.NET Membership بهمراه ASP.NET 2.0 در سال 2005 معرفی شد، و از آن زمان تا بحال تغییرات زیادی در چگونگی مدیریت احزار هویت و اختیارات کاربران توسط اپلیکیشن‌های وب بوجود آمده است. ASP.NET Identity نگاهی تازه است به آنچه که سیستم Membership هنگام تولید اپلیکیشن‌های مدرن برای وب، موبایل و تبلت باید باشد.

پیش زمینه: سیستم عضویت در ASP.NET


ASP.NET Membership

ASP.NET Membership طراحی شده بود تا نیازهای سیستم عضویت وب سایت‌ها را تامین کند، نیازهایی که در سال 2005 رایج بود و شامل مواردی مانند مدل احراز هویت فرم، و یک پایگاه داده SQL Server برای ذخیره اطلاعات کاربران و پروفایل هایشان می‌شد. امروزه گزینه‌های بسیار بیشتری برای ذخیره داده‌های وب اپلیکیشن‌ها وجود دارد، و اکثر توسعه دهندگان می‌خواهند از اطلاعات شبکه‌های اجتماعی نیز برای احراز هویت و تعیین سطوح دسترسی کاربرانشان استفاده کنند. محدودیت‌های طراحی سیستم ASP.NET Membership گذر از این تحول را دشوار می‌کند:
  • الگوی پایگاه داده آن برای SQL Server طراحی شده است، و قادر به تغییرش هم نیستید. می‌توانید اطلاعات پروفایل را اضافه کنید، اما تمام داده‌ها در یک جدول دیگر ذخیره می‌شوند، که دسترسی به آنها نیز مشکل‌تر است، تنها راه دسترسی Profile Provider API خواهد بود.
  • سیستم تامین کننده (Provider System) امکان تغییر منبع داده‌ها را به شما می‌دهد، مثلا می‌توانید از بانک‌های اطلاعاتی MySQL یا Oracle استفاده کنید. اما تمام سیستم بر اساس پیش فرض هایی طراحی شده است که تنها برای بانک‌های اطلاعاتی relational درست هستند. می‌توانید تامین کننده (Provider) ای بنویسید که داده‌های سیستم عضویت را در منبعی به غیر از دیتابیس‌های relational ذخیره می‌کند؛ مثلا Windows Azure Storage Tables. اما در این صورت باید مقادیر زیادی کد بنویسید. مقادیر زیادی هم  System.NotImplementedException باید بنویسید، برای متد هایی که به دیتابیس‌های NoSQL مربوط نیستند.
  • از آنجایی که سیستم ورود/خروج سایت بر اساس مدل Forms Authentication کار می‌کند، سیستم عضویت نمی‌تواند از OWIN استفاده کند. OWIN شامل کامپوننت هایی برای احراز هویت است که شامل سرویس‌های خارجی هم می‌شود (مانند Microsoft Accounts, Facebook, Google, Twitter). همچنین امکان ورود به سیستم توسط حساب‌های کاربری سازمانی (Organizational Accounts) نیز وجود دارد مانند Active Directory و Windows Azure Active Directory. این کتابخانه از OAuth 2.0، JWT و CORS نیز پشتیبانی می‌کند.

ASP.NET Simple Membership

ASP.NET simple membership به عنوان یک سیستم عضویت، برای فریم ورک Web Pages توسعه داده شد. این سیستم با WebMatrix و Visual Studio 2010 SP1 انتشار یافت. هدف از توسعه این سیستم، آسان کردن پروسه افزودن سیستم عضویت به یک اپلیکیشن Web Pages بود.
این سیستم پروسه کلی کار را آسان‌تر کرد، اما هنوز مشکلات ASP.NET Membership را نیز داشت. محدودیت هایی نیز وجود دارند:
  • ذخیره داده‌های سیستم عضویت در بانک‌های اطلاعاتی non-relational مشکل است.
  • نمی توانید از آن در کنار OWIN استفاده کنید.
  • با فراهم کننده‌های موجود ASP.NET Membership بخوبی کار نمی‌کند. توسعه پذیر هم نیست.

ASP.NET Universal Providers   

ASP.NET Universal Providers برای ذخیره سازی اطلاعات سیستم عضویت در Windows Azure SQL Database توسعه پیدا کردند. با SQL Server Compact هم بخوبی کار می‌کنند. این تامین کننده‌ها بر اساس Entity Framework Code First ساخته شده بودند و بدین معنا بود که داده‌های سیستم عضویت را می‌توان در هر منبع داده ای که توسط EF پشتیبانی می‌شود ذخیره کرد. با انتشار این تامین کننده‌ها الگوی دیتابیس سیستم عضویت نیز بسیار سبک‌تر و بهتر شد. اما این سیستم بر پایه زیر ساخت ASP.NET Membership نوشته شده است، بنابراین محدودیت‌های پیشین مانند محدودیت‌های SqlMembershipProvider هنوز وجود دارند. به بیان دیگر، این سیستم‌ها همچنان برای بانک‌های اطلاعاتی relational طراحی شده اند، پس سفارشی سازی اطلاعات کاربران و پروفایل‌ها هنوز مشکل است. در آخر آنکه این تامین کننده‌ها هنوز از مدل احراز هویت فرم استفاده می‌کنند.


ASP.NET Identity

همانطور که داستان سیستم عضویت ASP.NET طی سالیان تغییر و رشد کرده است، تیم ASP.NET نیز آموخته‌های زیادی از بازخورد‌های مشتریان شان بدست آورده اند.
این پیش فرض که کاربران شما توسط یک نام کاربری و کلمه عبور که در اپلیکیشن خودتان هم ثبت شده است به سایت وارد خواهند شد، دیگر معتبر نیست. دنیای وب اجتماعی شده است. کاربران از طریق وب سایت‌ها و شبکه‌های اجتماعی متعددی با یکدیگر در تماس هستند، خیلی از اوقت بصورت زنده! شبکه هایی مانند Facebook و Twitter.
همانطور که توسعه نرم افزار‌های تحت وب رشد کرده است، الگو‌ها و مدل‌های پیاده سازی نیز تغییر و رشد کرده اند. امکان Unit Testing روی کد اپلیکیشن‌ها، یکی از مهم‌ترین دلواپسی‌های توسعه دهندگان شده است. در سال 2008 تیم ASP.NET فریم ورک جدیدی را بر اساس الگوی (Model-View-Controller (MVC اضافه کردند. هدف آن کمک به توسعه دهندگان، برای تولید برنامه‌های ASP.NET با قابلیت Unit Testing بهتر بود. توسعه دهندگانی که می‌خواستند کد اپلیکیشن‌های خود را Unit Test کنند، همین امکان را برای سیستم عضویت نیز می‌خواستند.

با در نظر گرفتن تغییراتی که در توسعه اپلیکیشن‌های وب بوجود آمده ASP.NET Identity با اهداف زیر متولد شد:
  • یک سیستم هویت واحد (One ASP.NET Identity system)
    • سیستم ASP.NET Identity می‌تواند در تمام فریم ورک‌های مشتق از ASP.NET استفاده شود. مانند ASP.NET MVC, Web Forms, Web Pages, Web API و SignalR 
    • از این سیستم می‌توانید در تولید اپلیکیشن‌های وب، موبایل، استور (Store) و یا اپلیکیشن‌های ترکیبی استفاده کنید. 
  • سادگی تزریق داده‌های پروفایل درباره کاربران
    • روی الگوی دیتابیس برای اطلاعات کاربران و پروفایل‌ها کنترل کامل دارید. مثلا می‌توانید به سادگی یک فیلد، برای تاریخ تولد در نظر بگیرید که کاربران هنگام ثبت نام در سایت باید آن را وارد کنند.
  • کنترل ذخیره سازی/واکشی اطلاعات 
    • بصورت پیش فرض ASP.NET Identity تمام اطلاعات کاربران را در یک دیتابیس ذخیره می‌کند. تمام مکانیزم‌های دسترسی به داده‌ها توسط EF Code First کار می‌کنند.
    • از آنجا که روی الگوی دیتابیس، کنترل کامل دارید، تغییر نام جداول و یا نوع داده فیلد‌های کلیدی و غیره ساده است.
    • استفاده از مکانیزم‌های دیگر برای مدیریت داده‌های آن ساده است، مانند SharePoint, Windows Azure Storage Table و دیتابیس‌های NoSQL.
  • تست پذیری
    • ASP.NET Identity تست پذیری اپلیکیشن وب شما را بیشتر می‌کند. می‌توانید برای تمام قسمت هایی که از ASP.NET Identity استفاده می‌کنند تست بنویسید.
  • تامین کننده نقش (Role Provider)
    • تامین کننده ای وجود دارد که به شما امکان محدود کردن سطوح دسترسی بر اساس نقوش را می‌دهد. بسادگی می‌توانید نقش‌های جدید مانند "Admin" بسازید و بخش‌های مختلف اپلیکیشن خود را محدود کنید.
  • Claims Based
    • ASP.NET Identity از امکان احراز هویت بر اساس Claims نیز پشتیبانی می‌کند. در این مدل، هویت کاربر بر اساس دسته ای از اختیارات او شناسایی می‌شود. با استفاده از این روش توسعه دهندگان برای تعریف هویت کاربران، آزادی عمل بیشتری نسبت به مدل Roles دارند. مدل نقش‌ها تنها یک مقدار منطقی (bool) است؛ یا عضو یک نقش هستید یا خیر، در حالیکه با استفاده از روش Claims می‌توانید اطلاعات بسیار ریز و دقیقی از هویت کاربر در دست داشته باشید.
  • تامین کنندگان اجتماعی
    • به راحتی می‌توانید از تامین کنندگان دیگری مانند Microsoft, Facebook, Twitter, Google و غیره استفاده کنید و اطلاعات مربوط به کاربران را در اپلیکیشن خود ذخیره کنید.
  • Windows Azure Active Directory
    • برای اطلاعات بیشتر به این لینک مراجعه کنید.
  • یکپارچگی با OWIN
    • ASP.NET Identity بر اساس OWIN توسعه پیدا کرده است، بنابراین از هر میزبانی که از OWIN پشتیبانی می‌کند می‌توانید استفاده کنید. همچنین هیچ وابستگی ای به System.Web وجود ندارد. ASP.NET Identity یک فریم ورک کامل و مستقل برای OWIN است و می‌تواند در هر اپلیکیشنی که روی OWIN میزبانی شده استفاده شود.
    • ASP.NET Identity از OWIN برای ورود/خروج کاربران در سایت استفاده می‌کند. این بدین معنا است که بجای استفاده از Forms Authentication برای تولید یک کوکی، از OWIN CookieAuthentication استفاده می‌شود.
  • پکیج NuGet
    • ASP.NET Identity در قالب یک بسته NuGet توزیع می‌شود. این بسته در قالب پروژه‌های ASP.NET MVC, Web Forms و Web API که با Visual Studio 2013 منتشر شدند گنجانده شده است.
    • توزیع این فریم ورک در قالب یک بسته NuGet این امکان را به تیم ASP.NET می‌دهد تا امکانات جدیدی توسعه دهند، باگ‌ها را برطرف کنند و نتیجه را بصورت چابک به توسعه دهندگان عرضه کنند.

شروع کار با ASP.NET Identity

ASP.NET Identity در قالب پروژه‌های ASP.NET MVC, Web Forms, Web API و SPA که بهمراه Visual Studio 2013 منتشر شده اند استفاده می‌شود. در ادامه به اختصار خواهیم دید که چگونه ASP.NET Identity کار می‌کند.
  1. یک پروژه جدید ASP.NET MVC با تنظیمات Individual User Accounts بسازید.

  2. پروژه ایجاد شده شامل سه بسته می‌شود که مربوط به ASP.NET Identity هستند: 

  • Microsoft.AspNet.Identity.EntityFramework این بسته شامل پیاده سازی ASP.NET Identity با Entity Framework می‌شود، که تمام داده‌های مربوطه را در یک دیتابیس SQL Server ذخیره می‌کند.
  • Microsoft.AspNet.Identity.Core این بسته محتوی تمام interface‌‌های ASP.NET Identity است. با استفاده از این بسته می‌توانید پیاده سازی دیگری از ASP.NET Identity بسازید که منبع داده متفاوتی را هدف قرار می‌دهد. مثلا Windows Azure Storage Table و دیتابیس‌های NoSQL.
  • Microsoft.AspNet.Identity.OWIN این بسته امکان استفاده از احراز هویت OWIN را در اپلیکیشن‌های ASP.NET فراهم می‌کند. هنگام تولید کوکی‌ها از OWIN Cookie Authentication استفاده خواهد شد.
اپلیکیشن را اجرا کرده و روی لینک Register کلیک کنید تا یک حساب کاربری جدید ایجاد کنید.

هنگامیکه بر روی دکمه‌ی Register کلیک شود، کنترلر Account، اکشن متد Register را فراخوانی می‌کند تا حساب کاربری جدیدی با استفاده از ASP.NET Identity API ساخته شود.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser() { UserName = model.UserName };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInAsync(user, isPersistent: false);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            AddErrors(result);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

اگر حساب کاربری با موفقیت ایجاد شود، کاربر توسط فراخوانی متد SignInAsync به سایت وارد می‌شود.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser() { UserName = model.UserName };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInAsync(user, isPersistent: false);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            AddErrors(result);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

    var identity = await UserManager.CreateIdentityAsync(
       user, DefaultAuthenticationTypes.ApplicationCookie);

    AuthenticationManager.SignIn(
       new AuthenticationProperties() { 
          IsPersistent = isPersistent 
       }, identity);
}

از آنجا که ASP.NET Identity و OWIN Cookie Authentication هر دو Claims-based هستند، فریم ورک، انتظار آبجکتی از نوع ClaimsIdentity را خواهد داشت. این آبجکت تمامی اطلاعات لازم برای تشخیص هویت کاربر را در بر دارد. مثلا اینکه کاربر مورد نظر به چه نقش هایی تعلق دارد؟ و اطلاعاتی از این قبیل. در این مرحله می‌توانید Claim‌‌های بیشتری را به کاربر بیافزایید.

کلیک کردن روی لینک Log off در سایت، اکشن متد LogOff در کنترلر Account را اجرا می‌کند.

// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    AuthenticationManager.SignOut();
    return RedirectToAction("Index", "Home");
}

همانطور که مشاهده می‌کنید برای ورود/خروج کاربران از AuthenticationManager استفاده می‌شود که متعلق به OWIN است. متد SignOut همتای متد FormsAuthentication.SignOut است.


کامپوننت‌های ASP.NET Identity

تصویر زیر اجزای تشکیل دهنده ASP.NET Identity را نمایش می‌دهد. بسته هایی که با رنگ سبز نشان داده شده اند سیستم کلی ASP.NET Identity را می‌سازند. مابقی بسته‌ها وابستگی هایی هستند که برای استفاده از ASP.NET Identity در اپلیکیشن‌های ASP.NET لازم اند.

دو پکیج دیگر نیز وجود دارند که به آنها اشاره نشد:

  • Microsoft.Security.Owin.Cookies این بسته امکان استفاده از مدل احراز هویت مبتنی بر کوکی (Cookie-based Authentication) را فراهم می‌کند. مدلی مانند سیستم ASP.NET Forms Authentication.
  • EntityFramework که نیازی به معرفی ندارد.


مهاجرت از Membership به ASP.NET Identity

تیم ASP.NET و مایکروسافت هنوز راهنمایی رسمی، برای این مقوله ارائه نکرده اند. گرچه پست‌های وبلاگ‌ها و منابع مختلفی وجود دارند که از جنبه‌های مختلفی به این مقوله پرداخته اند. امیدواریم تا در آینده نزدیک مایکروسافت راهنمایی‌های لازم را منتشر کند، ممکن است ابزار و افزونه هایی نیز توسعه پیدا کنند. اما در یک نگاه کلی می‌توان گفت مهاجرت بین این دو فریم ورک زیاد ساده نیست. تفاوت‌های فنی و ساختاری زیادی وجود دارند، مثلا الگوی دیتابیس‌ها برای ذخیره اطلاعات کاربران، مبتنی بودن بر فریم ورک OWIN و غیره. اگر قصد اجرای پروژه جدیدی را دارید پیشنهاد می‌کنم از فریم ورک جدید مایکروسافت ASP.NET Identity استفاده کنید.


قدم‌های بعدی

در این مقاله خواهید دید چگونه اطلاعات پروفایل را اضافه کنید و چطور از ASP.NET Identity برای احراز هویت کاربران توسط Facebook و Google استفاده کنید.
پروژه نمونه ASP.NET Identity می‌تواند مفید باشد. در این پروژه نحوه کارکردن با کاربران و نقش‌ها و همچنین نیازهای مدیریتی رایج نمایش داده شده. 
نظرات مطالب
پایان پروژه ASP.NET Ajax Control Toolkit !
مایکروسافت ASP.NET Ajax را با اون عظمت و زحمتی که براش کشیده بودند، در مقابل jQuery بازنده اعلام کرده الان شما صحبت از Anthem.Net می‌کنید که فقط منحصر است به ASP.NET web forms آن هم نگارش‌های قبل از سه آن + پشتیبانی از مرورگرهای مختلف هم در آن ضعیف است.
هدف مایکروسافت از اینکار مدیریت هر دو پروژه MVC و Web forms است آن هم با هزینه کم، کیفیت بالا و سازگار با تمام مرورگرها.
ضمنا این رو در نظر باشید که یکی از توانمندی‌های jQuery، Ajax است (از کار با DOM گرفته تا دستکاری CSS نمایش داده شده، تا Animation ، مدیریت ساده‌تر رخدادها، اعمال قالب به سایت و غیره) و این مورد مزیت مهمی است نسبت به تمام کتابخانه‌هایی که فقط برای یک کار و آن هم سهولت تولید برنامه‌های مبتنی بر Ajax ایجاد شده‌اند و از چند مشکل مهم رنج می‌برند:
- تک کاره‌اند. فقط Ajax .
- مشکل سازگاری با مرورگرهای مختلف را دارند.
- به صورت فعال توسعه داده نمی‌شوند؛ رفع باگ نمی‌شوند و غیره. برای مثال فواصل به روز رسانی همان Anthem.Net را بررسی کنید.
- توسعه پذیر نیستند. برای مثال آیا می‌توان برای Anthem.Net افزونه نوشت؟
- حجم بالایی دارند.
- سرعت پایینی دارند.

jQuery در مورد تمام موارد عنوان شده حرف برای گفتن دارد از حجم کم تا سرعت بالاتر نسبت به اکثر کتابخانه‌های جاوا اسکریپتی دیگر تا توسعه‌ی منظم، سازگاری عالی با مرورگرها، توسعه پذیری و صدها و هزاران افزونه‌ی مهیا برای آن و غیره.

و RAD هزینه بر است. یعنی چی؟ یعنی حجم بالای کدهای اسکریپتی که باید به برنامه‌ی شما مثلا توسط ASP.NET Ajax تزریق شود که مبادا شما بخواهید دست خودتان را به نوشتن چند سطر کد جاوا اسکریپتی آلوده کنید. همچنین حجم تبادل اطلاعات ASP.NET Ajax را هم که مبتنی است بر RAD را هم با حجم اطلاعات مبادله شده توسط jQuery مقایسه کنید (با پلاگین فایرباگ مربوط به فایرفاکس). این حجم واقعا زیاد است و قابل مقایسه نیست. (تمام این‌ها هزینه‌های RAD است)
ضمنا وجود 100 ها افزونه و پلاگین نوشته شده برای jQuery کار شما را بسیار بسیار ساده می‌کنند، مانند پاسخ قبلی من در این مطلب.
فقط باید کمی وقت بگذارید و چیزی را بیاموزید که واقعا ارزش دارد. گیرم فردا نخواستید با ASP.NET کار کنید. تمام این اطلاعات در PHP هم به درد شما می‌خورد، چون قسمت سمت کلاینت آنچنان تفاوتی نمی‌کند و jQuery یک کتابخانه‌ی سمت کلاینت است.
مطالب
بررسی تغییرات Blazor 8x - قسمت اول - معرفی SSR
از لحاظ تاریخی، Blazor به همراه دو حالت اصلی است:
- Blazor Server، که در آن یک اتصال SignalR، بین مرورگر کاربر و سرور، برقرار شده و سرور حالات مختلف این جلسه‌ی کاری را مدیریت می‌کند. آغاز این حالت، بسیار سریع است؛ اما وجود اتصال دائم SignalR در آن ضروری است. نیاز به وجود این اتصال دائم، با تعداد بالای کاربر می‌تواند کارآیی سرور را تحت تاثیر قرار دهد.
- Blazor WASM: در این حالت کل برنامه‌ی Blazor، درون مرورگر کاربر اجرا می‌شود و برای اینکار الزاما نیازی به سرور ندارد؛ اما آغاز اولیه‌ی آن به علت نیاز به بارگذاری کل برنامه درون مرورگر کاربر، اندکی کند است. اتصال این روش با سرور، از طریق روش‌های متداول کار با Web API صورت می‌گیرد و نیازی به اتصال دائم SignalR را ندارد.

دات نت 8، دو تغییر اساسی را در اینجا ارائه می‌دهد:
- در اینجا حالت جدیدی به نام SSR یا Static Server Rendering ارائه شده‌است (به آن Server-side rendering هم می‌گویند). در این حالت نه WASM ای درون مرورگر کاربر اجرا می‌شود و نه اتصال دائم SignalR ای برای کار با آن نیاز است! در این حالت برنامه تقریبا همانند یک MVC Razor application سنتی کار می‌کند؛ یعنی سرور، کار رندر نهایی HTML قابل ارائه‌ی به کاربر را انجام داده و آن‌را به سمت مرورگر، برای نمایش ارسال می‌کند و همچنین سرور، هیچ حالتی را هم از برنامه ذخیره نمی‌کند و به‌علاوه، کلاینت نیز نیازی به دریافت کل برنامه را در ابتدای کار ندارد (هم آغاز و نمایش سریعی را دارد و هم نیاز به منابع کمتری را در سمت سرور برای اجرا دارد).
- تغییر مهم دیگری که در دات نت 8 صورت گرفته، امکان ترکیب کردن حالت‌های مختلف رندر صفحات، در برنامه‌های Blazor است. یعنی می‌توان یک صفحه‌ی SSR را داشت که تنها قسمت کوچکی از آن بر اساس معماری Blazor Server کار کند (قسمت‌‌های اصطلاحا interactive یا تعاملی آن). یا حتی در یک برنامه، امکان ترکیب Blazor Server و Blazor WASM نیز وجود دارد.

این‌ها عناوین موارد جدیدی هستند که در این سری به تفصیل بررسی خواهیم کرد.


تاریخچه‌ی نمایش صفحات وب در مرورگرها

در ابتدای ارائه‌ی وب، سرورها، ابتدا درخواستی را از طرف مرورگر کلاینت دریافت می‌کردند و در پاسخ به آن، HTML ای را تولید و بازگشت می‌دادند. حاصل آن، نمایش یک صفحه‌ی استاتیک non-interactive بود (غیرتعاملی). علت تاکید بر روی واژه‌ی interactive (تعاملی)، بکارگیری گسترده‌ی آن در نگارش جدید Blazor است؛ تا حدی که ایجاد قالب‌های جدید آغازین برنامه‌های آن، با تنظیم این گزینه همراه است. برای مشاهده‌ی آن، پس از نصب SDK جدید دات نت، دستور dotnet new blazor --help را صادر کنید.
سپس JavaScript از راه رسید و هدف آن، افزودن interactivity به صفحات سمت کاربر بود تا بتوان بر اساس تعاملات و ورودی‌های کاربر، تغییراتی را بر روی محتوای صفحه اعمال کرد. در ادامه JavaScript این امکان را یافت تا بتواند درخواست‌هایی را به سمت سرور ارسال کند و بر اساس خروجی دریافتی، قسمت‌هایی از صفحه‌ی جاری استاتیک را به صورت پویا تغییر دهد.
در ادامه با بالارفتن توانمندی‌های سخت‌افزاری و همچنین توسعه‌ی کتابخانه‌های جاوااسکریپتی، به برنامه‌های تک صفحه‌ای کاملا پویا و interactive رسیدیم که به آن‌ها SPA گفته می‌شود (Single-page applications)؛ از این دست کتابخانه‌ها می‌توان به Backbone اشاره کرد و پس از آن به React و Angular. برنامه‌های Blazor نیز اخیرا به این جمع اضافه شده‌اند.
اما ... اخیرا توسعه دهنده‌ها به این نتیجه رسیده‌اند که SPAها برای تمام امور، مناسب و یا حتی الزامی نیستند. گاهی از اوقات ما فقط نیاز داریم تا محتوایی را خیلی سریع و بهینه تولید و بازگشت دهیم؛ مانند نمایش لیست اخبار، به هزاران دنبال کننده، با حداقل مصرف منابع و در همین حال نیاز به interactivity در بعضی از قسمت‌های خاص نیز احساس می‌شود. این رویه‌ای است که در تعدادی از فریم‌ورک‌های جدید و مدرن جاوااسکریپتی مانند Astro در پیش گرفته شده‌است؛ در آن‌ها ترکیبی از رندر سمت سرور، به همراه interactivity سمت کاربر، مشاهده می‌شود. برای مثال این امکان را فراهم می‌کنند تا محتوای قسمتی از صفحه را در سمت سرور تهیه و رندر کنید، یا قسمتی از صفحه (یک کامپوننت خاص)، به صورت interactive فعال شود. ترکیب این دو مورد، دقیقا هدف اصلی Blazor، در دات نت 8 است. برای مثال فرض کنید می‌خواهید برنامه و سایتی را طراحی کنید که چند صفحه‌ی آغازین آن، بدون هیچگونه تعاملی با کاربر هستند و باید سریع و SEO friendly باشند. همچنین تعدادی از صفحات آن هم قرار است فقط یک سری محتوای ثابت را نمایش دهند، اما در قسمت‌های خاصی از آن نیاز به تعامل با کاربر است.


معرفی Blazor یکپارچه در دات نت 8

مهم‌ترین تغییر Blazor در دات نت 8، یکپارچه شدن حالت‌های مختلف رندر آن در سمت سرور است. تغییرات زیاد رخ داده‌اند تا امکان داشتن Server-side rendering یا SSR به همراه قابلیت فعال سازی interactivity به ازای هر کامپوننت دلخواه که به آن حالت‌های رندر (Render modes) گفته می‌شود، میسر شوند. در اساس، این روش جدید، همان Blazor Server بهبود یافته‌است که حالت SSR، حالت پیش‌فرض آن است. در کنار آن قابلیت‌های راهبری (navigation)، نیز بهبود یافته‌اند تا برنامه‌های SSR همانند برنامه‌های SPA به‌نظر برسند.

در دات نت 8، ASP.NET Core و Blazor نیز کاملا یکپارچه شده‌اند. در این حالت برنامه‌های Blazor Server می‌توانند همانند برنامه‌های MVC Razor Pages متداول، با کمک قابلیت SSR، صفحات غیر interactive ای را رندر کنند؛ البته به کمک کامپوننت‌های Razor. مزیت آن نسبت به  MVC Razor Pages این است که اکنون می‌توانید هر کامپوننت مجزایی از صفحه را نیز کاملا interactive کنید.
در نگارش‌های قبلی Blazor، برنامه‌های Blazor Server حتی برای شروع کار نیاز به یک صفحه‌ی Razor Pages آغازین داشتند، اما دیگر نیازی به این مورد با دات نت  8 نیست؛ چون ASP.NET Core 8x می‌تواند کامپوننت‌های Razor را نیز به صورت HTML خالص بازگشت دهد و یا Minimal API آن به همراه خروجی new RazorComponentResult نیز شده‌است. در حالت SSR، حتی سیستم مسیریابی ASP.NET Core نیز با Blazor یکی شده‌است.

البته این تغییرات، حالت‌های خالص Blazor WebAssembly و یا MAUI Blazor Hybrid را تحت تاثیر قرار نمی‌دهند؛ اما بدیهی است تمام آن‌ها از سایر قابلیت‌های جدید اضافه شده نیز بهره‌مند هستند.


معرفی حالت‌های مختلف رندر Blazor در دات نت 8

یک برنامه‌ی جدید 8x Blazor، در اساس بر روی سرور رندر می‌شود (همان SSR). اما همانطور که عنوان شد، این SSR ارائه شده‌ی توسط Blazor، یک قابلیت مهم را نسبت به MVC Razor pages دارد و آن هم امکان فعالسازی interactivity، به ازای کامپوننت‌ها و قسمت‌های کوچکی از صفحه است که واقعا نیاز است تعاملی باشند. فعالسازی آن هم بسیار ساده، یک‌دست و یکپارچه است:
@* For being rendered on the server *@
<Counter @rendermode="@InteractiveServer" />

@* For running in WebAssembly *@
<Counter @rendermode="@InteractiveWebAssembly" />
در این حالت می‌توان مشخص کرد که آیا قرار است این کامپوننت خاصی که در قسمتی از صفحه‌ی جاری قرار است رندر شود، نیاز است به کمک فناوری وب‌اسمبلی اجرا شود و یا قرار است بر روی سرور رندر شود؟

این تعاریف حالت رندر را توسط دایرکتیوها نیز می‌توان به ازای هر کامپوننت مجزا، مشخص کرد (یکی از این دو حالت باید بکار گرفته شود):
@rendermode InteractiveServer

@rendermode InteractiveWebAssembly
حالت رندر مشخص شده، توسط زیرکامپوننت‌های تشکیل دهنده‌ی این کامپوننت‌ها نیز به ارث برده می‌شوند؛ اما امکان ترکیب آن‌ها با هم نیست. یعنی اگر حالت رندر را InteractiveServer انتخاب کردید، زیرکامپوننت‌های تشکیل دهنده‌ی آن نمی‌توانند حالت دیگری را انتخاب کنند.
امکان اعمال این ویژگی‌ها به مسیریاب برنامه نیز وجود دارد که در این حالت کل برنامه را interactive می‌کند. اما در حالت پیش‌فرض، برنامه‌ای که ایجاد می‌شود فاقد تنظیمات تعاملی در ریشه‌ی اصلی آن است.


معرفی حالت رندر خودکار در Blazor 8x

یکی دیگر از حالت‌های رندر معرفی شده‌ی در Blazor 8x، حالت Auto است:
<Counter @rendermode="@InteractiveAuto" />
این حالت رندر، به صورت پیش‌فرض از WebAssembly استفاده می‌کند؛ اما فقط زمانیکه فایل‌های مرتبط با آن کاملا دریافت شده‌باشند. یعنی در ابتدای کار برای ارائه‌ی امکانات تعاملی، از حالت سریع و سبک InteractiveServer استفاده می‌کند؛ اما در پشت صحنه مشغول به دریافت فایل‌های مرتبط با نگارش وب‌اسمبلی کامپوننت فوق خواهد شد. پس از بارگذاری و کش شدن این فایل‌ها، برای بارهای بعدی رندر، فقط از حالت وب‌اسمبلی استفاده می‌کند.


معرفی حالت رندر Streaming در Blazor 8x

در بار اول بارگذاری صفحات، ممکن است دریافت اطلاعات مرتبط با آن کمی کند و با وقفه باشند. در این حالت برای اینکه برنامه‌های SSR یک صفحه‌ی خالی را نمایش ندهند، می‌توان در ابتدا با استفاده از حالت رندر جدید StreamRendering، حداقل قالب صفحه را نمایش داد و سپس اصل اطلاعات را:
@attribute [StreamRendering(prerender: true)]
این روش، از HTTP Streaming در پشت صحنه استفاده کرده و مرحله به مرحله قسمت‌های تکمیل شده را به سمت مرورگر کاربر، برای نمایش نهایی ارسال می‌کند.


جزئیات بیشتر نحوه‌ی کار با این حالات را در قسمت‌های بعدی بررسی خواهیم کرد.


نتیجه گیری:

روش‌های جدید رندر ارائه شده‌ی در Blazor 8x، برای موارد زیر مفید هستند:
- زمانیکه قسمت عمده‌ای از برنامه‌ی شما بر روی سرور اجرا می‌شود.
- زمانیکه خروجی اصلی برنامه‌ی شما بیشتر حاوی محتواهای ثابت است؛ مانند CMSها.
- زمانیکه می‌خواهید صفحات شما قابل ایندکس شدن توسط موتورهای جستجو باشند و مباحث SEO برای شما مهم است.
- زمانیکه نیاز به مقدار کمی امکانات تعاملی دارید و فقط قسمت‌های کوچکی از صفحه قرار است تعاملی باشند. برای مثال فقط قرار است قسمت کوچکی از یک صفحه‌ی نمایش مقاله‌ای از یک بلاگ، به همراه امکان رای دادن به آن مطلب (تنها قسمت «تعاملی» صفحه) باشد.
- و یا زمانیکه می‌خواهید MVC Razor Pages را با یک فناوری جدید که امکانات بیشتری را در اختیار شما قرار می‌دهد، جایگزین کنید.
نظرات اشتراک‌ها
نگارش بعدی ASP.NET Core از Full .NET Framework پشتیبانی نمی‌کند
بحث اصلی مطلب جاری این است که NET Core. (پیاده سازی) با NET Standard. (قرارداد) یکی نیست. NET Core. یکی از پیاده سازی‌های NET Standard. است؛ مانند دات نت 4.6.1 که آن هم پیاده سازی کننده‌ی دات نت استاندارد 2 است. هر دوی این‌ها دارای یک سری API خاص خودشان هم هستند که در NET Standard. وجود ندارند. سطح API دات نت Core هم بیشتر است از NET Standard. و در یکسری از موارد هم کاملا ناسازگار با دات نت کامل. بنابراین توافقی که در اینجا وجود دارد، صرفا پیاده سازی قرارداد NET Standard. است و بیشتر از آن هم مربوط است به توسعه دهندگان آن سکوی کاری خاص که الزامی به یکی بودن آن‌ها نیست.
کاری که پیشتر می‌خواستند انجام دهند، محدود کردن ASP.NET Core به سطح API موجود در NET Core. بود (NET Core 2.0 only. یا تصویر زیر) و نه صرفا به NET Standard. . این مساله برای توسعه دهندگان ASP.NET Core می‌توانست فوق العاده باشد؛ چون سطح API بیشتر و به‌روزتری را در اختیارشان قرار می‌داد و اگر قابلیتی در NET Standard. وجود نداشت، نمی‌بایستی درخواست می‌دادند تا اضافه شود تا بعد بتوانند استفاده کنند.


اما چون این مساله و سطح API بیشتر و گاهی از اوقات کاملا متفاوت، سازگاری با کتابخانه‌هایی را که در میدان دید این API قرار نمی‌گرفتند، زیر سؤال می‌برد، ارتقاء برنامه‌های قبلی را با مشکل مواجه می‌کرد. به همین جهت تصمیم گرفته‌اند که ASP.NET Core را سازگار با دات نت فریم ورک کامل نیز ارائه دهند و بنابراین «محدودش کنند» به NET Standard 2.0.  و نه حالت NET Core only‌. قبلی: اطلاعات بیشتر


به علاوه باید درنظر داشت که امکان اضافه کردن یک بسته‌ی نیوگت از یک کتابخانه‌ی نوشته شده‌ی برای دات نت کامل در برنامه‌های دات نت Core به معنای تضمینی برای کار کردن آن در زمان اجرا نخواهد بود. از این جهت که دات نت کامل، به همراه قسمت‌هایی است که در NET Standard. وجود خارجی ندارند. بنابراین اگر کتابخانه‌ی استفاده شده صرفا این API مشترک را هدف قرار داده‌است، هم قابلیت اتصال و هم قابلیت اجرا را خواهد داشت؛ اما اگر برای مثال کسی بسته‌ی NServiceBus را به پروژه‌ی ASP.NET Core 2.0 اضافه کند، بدون مشکل کامپایل خواهد شد. اما از آنجائیکه این کتابخانه از MSMQ استفاده می‌کند که خارج از میدان دید این استاندارد است، در زمان اجرا با شکست مواجه خواهد شد.
نظرات مطالب
ASP.NET MVC #1
ASP.NET Web API وابستگی به ASP.NET MVC ندارد و در برنامه‌های وب فرم هم قابل استفاده‌است (یا حتی در یک سرویس ویندوز NT). در برنامه‌های ASP.NET MVC فعلی امکان استفاده‌ی از امکانات آن در Viewهای برنامه وجود دارد. این جزئیات در مطالب «گروه ASP.NET Web API» بیشتر بررسی شده‌اند.
مسیرراه‌ها
+AngularJS 2.0
شروع به کار با AngularJS 2.0 و TypeScript
فرم‌های مبتنی بر قالب‌ها در Angular
Angular Animation
آپلود فایل
Angular Material 6x
  • ابزارهای توسعه