نظرات مطالب
کار با Areas در ASP.NET Core
سلام برای ساخت api controller در Area مسیر یابی به چه شکل میشود .
ممنون
بنده هم به همین ارور و عدم دسترسی این api در ایران برخوردم..ایا راه حلی برای این موضوع هست ؟
لطفا این قسمت « بهترین روش برای ایجاد یک سبد خرید استفاده از یک Api Controller میباشد.» را بیشتر توضیح بدید. با تشکر.
نظرات مطالب
BloggerToCHM
نگارش جدید برنامه
http://vahid.nasiri.googlepages.com/BloggerToCHM_1.3_setup.exe
سازگار با نگارش جدید API بلاگر
و ...
http://vahid.nasiri.googlepages.com/BloggerToCHM_1.3_setup.exe
سازگار با نگارش جدید API بلاگر
و ...
این سایت هم سرویس thumbnail ارائه میدهد:
http://www.pageglimpse.com/features/api
http://www.pageglimpse.com/features/api
آموزش PouchDB : معرفی
هدف این مقاله بر این است که شما را با دیتابیس PouchDB آشنا سازد .
در مطلب اول هدف فقط آشنایی و نحوه نصب PouchDB قرار خوهد داشت و در مطالب بعدی نحوه آشنایی با نحوه کدنویسی و استفاده به صورت آفلاین یا آنلاین بررسی خواهد شد .
فهرست مطالب :
- بخش اول : معرفی PouchDB
- شروع به کار با PouchDB
- نحوه استفاده از API ها
- سوالات متداول در مورد PouchDB
- خطاهای احتمالی
- پروژهها و پلاگین های PouchDB
PouchDB یک دیتابیس NoSQL میباشد که به وسیله Javascript نوشته شده و هدف آن این است که برنامه نویسها بتوانند برنامههایی را توسعه و ارائه کنند که بتواند هم به صورت آفلاین و هم آنلاین سرویس دهی داشته باشند.
برنامه اطلاعات خودش را به صورت آفلاین ذخیره میکند و کاربر میتواند زمانیکه به اینترنت متصل نیست، از آنها استفاده کند. اما به محض اتصال به اینترنت، دیتابیس خودش را با دیتابیس آنلاین همگام (Sync) میکند. اینجاست که قدرت اصلی PouchDB مشخص میشود.
بزرگترین برتری PouchDB همین است. دیتابیسی است که به صورت توکار قابلیتهای همگام سازی را دارا میباشد و به صورت اتوماتیک این کار را انجام میدهد.
PouchDB یک پروژهی اوپن سورس است که توسط این افراد به روز میشود. البته باید گفت که PouchDB از CouchDB الهام گرفته شده است. اگر شما هم قصد همکاری در این پروژه را دارید بهتر است که راهنمای همکاری را مطالعه کنید .
پشتیبانی مرورگرها
PouchDB پیش زمینههای مختلفی دارد که به آن این امکان را میدهد تا روی همه مرورگرها و صد البته روی NodeJs کار کند. از IndexedDB بر روی Firefox/Chrome/Opera/IE و WebSql بر روی Safari و همچنین LevelDB بر روی NodeJs استفاده میکند.
در حال حاظر PouchDB بر روی مرورگرهای زیر تست شده است:
- فایرفاکس 12 و بالاتر
- گوگل کروم 19 و بالاتر
- اپرا 12 و بالاتر
- سافاری 5 و بالاتر
- اینترنت اکسپلورر 10 و بالاتر
- NodeJs 0.10 و بالاتر
- و به صورت شگفت انگیزی در Apache Cordova
برای اطلاعات بیشتر در مورد مرورگرهایی که IndexdDB و WebSql را پشتیبانی میکنند به لینکهای زیر مراجعه کنید:
نکته : در صورتی که برنامه شما نیاز دارد تا از اینترنت اکسپلورر نسخه پایینتر از 10 استفاده کند میتوانید از دیتابیسهای آنلاین استفاده کنید، که البته دیگر قابلیت استفاده آفلاین را نخواهد داشت.
وضعیت فعلی PouchDB
PouchDB برای مرورگر، فعلا در وضعیت بتا به سر میبرد و به صورت فعالی در حال گذراندن تست هایی میباشد تا باگهای آن برطرف شود و به صورت پایدار (Stable ) ارائه گردد. البته فقط ممکن است که شما باگی را در قسمت Apiها پیدا کنید که البته Apiها هم در حال حاضر پایدار هستند و گزارشی مبنی بر باگ در آنها موجود نیست. اگر هم باگی پیدا بشود شما میتوانید PouchDB را بدون ریسک از دست رفتن اطلاعات آپگرید کنید.
PouchDB برای NodeJs فعلا در وضعیت آلفا است و آپگرید کردن ممکن است به اطلاعات شما آسیب بزند. البته با آپدیت به صورت دستی خطری شما را تهدید نخواهد کرد .
نحوهی نصب PouchDB
PouchDB به صورت یک کتابخانهی کوچک و جمع و جور طراحی شده است تا بتواند همه نیازها را برطرف و روی همه نوع Device اعم از موبایل، تبلت، مرورگر و کلا هر چیزی که جاوا اسکریپت را ساپورت میکند کار خود را به خوبی انجام بدهد.
برای استفاده از PouchDB میبایست این فایل را با حجم فوق العاده 97 کیلوبایت دانلود کنید و آن را به یک صفحه وب اضافه کنید :
<script src="pouchdb-2.1.0.min.js"></script>
آخرین نسخه و بهترین نسخه : pouchdb-2.1.0.min.js
برای اطلاع از آخرین آپدیتها و نسخهها به این صفحه در گیت هاب مراجعه کنید .
برای کسانی هم که از NodeJS استفاده میکنند نحوه نصب به این صورت است :
$ npm install pouchdb
در 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()); } }