اشتراکگذاری منابع متقابل مبدأ چیست؟
اشتراکگذاری منابع متقابل مبدأ (CORS) مکانیزمی برای یکپارچهسازی برنامهها است. CORS روشی را تعریف میکند که برنامههای وب کلاینت که در یک دامنه بارگذاری میشوند، بتوانند با منابع در دامنهای متفاوت تعامل داشته باشند. این امر مفید است زیرا برنامههای پیچیده اغلب به APIها و منابع شخص ثالث در کد سمت کلاینت خود ارجاع میدهند. برای مثال، برنامه شما ممکن است از مرورگرتان برای دریافت ویدیوها از API یک پلتفرم ویدیویی، استفاده از فونتها از یک کتابخانه فونت عمومی یا نمایش دادههای آب و هوایی از یک پایگاه داده ملی آب و هوا استفاده کند. CORS به مرورگر کلاینت اجازه میدهد قبل از انتقال هرگونه داده، با سرورهای شخص ثالث بررسی کند که آیا درخواست مجاز است یا خیر.
چرا اشتراکگذاری منابع متقابل مبدأ مهم است؟
در گذشته، زمانی که فناوریهای اینترنت هنوز جدید بودند، مشکلات جعل درخواست بین سایتی (CSRF) رخ میداد. این مشکلات درخواستهای کلاینت جعلی را از مرورگر قربانی به برنامه دیگری ارسال میکرد.برای مثال، قربانی وارد برنامه بانکی خود میشد. سپس فریب میخورد تا یک وبسایت خارجی را در یک تب مرورگر جدید بارگذاری کند. وبسایت خارجی سپس از اعتبارنامههای کوکی قربانی استفاده میکرد و دادهها را به برنامه بانکی منتقل میکرد و خود را به عنوان قربانی جا میزد. کاربران غیرمجاز سپس دسترسی ناخواسته به برنامه بانکی پیدا میکردند.برای جلوگیری از چنین مشکلات CSRF، همه مرورگرها اکنون سیاست مبدأ یکسان را اجرا میکنند.
سیاست مبدأ یکسان
امروزه، مرورگرها اعمال میکنند که کلاینتها فقط میتوانند درخواستها را به منبعی با مبدأ یکسان با URL کلاینت ارسال کنند. پروتکل، پورت و نام میزبان URL کلاینت باید با سروری که درخواست میکند مطابقت داشته باشند.
برای مثال، مقایسه مبدأ را برای URLهای زیر با URL کلاینت http://store.aws.com/dir/page.html در نظر بگیرید.
URL | نتیجه | دلیل |
http://store.aws.com/dir2/new.html | مبدأ یکسان | فقط مسیر متفاوت است |
http://store.aws.com/dir/inner/other.html | مبدأ یکسان | فقط مسیر متفاوت است |
https://store.aws.com/page.html | مبدأ متفاوت | پروتکل متفاوت است |
http://store.aws.com:81/dir/page.html | مبدأ متفاوت | پورت متفاوت است (http:// به طور پیش فرض پورت ۸۰ است) |
http://news.aws.com/dir/page.html | مبدأ متفاوت | میزبان متفاوت است |
بنابراین، سیاست مبدأ یکسان بسیار امن است اما برای موارد استفاده واقعی انعطافپذیر نیست.اشتراکگذاری منابع متقابل مبدأ (CORS) توسعهای از سیاست مبدأ یکسان است. برای اشتراکگذاری منابع مجاز با اشخاص ثالث خارجی به آن نیاز دارید. برای مثال، زمانی که میخواهید دادهها را از APIهای خارجی که عمومی یا مجاز هستند دریافت کنید، به CORS نیاز دارید. همچنین اگر میخواهید دسترسی مجاز شخص ثالث به منابع سرور خود را مجاز کنید، به CORS نیاز دارید.
اشتراکگذاری منابع متقابل مبدأ چگونه کار میکند؟
در ارتباطات استاندارد اینترنتی، مرورگر شما یک درخواست HTTP به سرور برنامه ارسال میکند، دادهها را به عنوان پاسخ HTTP دریافت میکند و آن را نمایش میدهد. در اصطلاحات مرورگر، URL فعلی مرورگر، مبدأ فعلی و URL شخص ثالث، مبدأ متقابل نامیده میشود.
هنگامی که یک درخواست متقابل مبدأ ارسال میکنید، فرآیند درخواست-پاسخ به این صورت است:
- مرورگر یک هدر مبدأ با اطلاعات مربوط به پروتکل، میزبان و پورت مبدأ فعلی به درخواست اضافه میکند.
- سرور هدر مبدأ فعلی را بررسی میکند و با دادههای درخواستی و هدر Access-Control-Allow-Origin پاسخ میدهد.
- مرورگر هدرهای درخواست کنترل دسترسی را میبیند و دادههای برگشتی را با برنامه کلاینت به اشتراک میگذارد.
- در غیر این صورت، اگر سرور نمیخواهد دسترسی متقابل مبدأ را مجاز کند، با یک پیام خطا پاسخ میدهد.
مثال اشتراکگذاری منابع متقابل مبدأ
برای مثال، سایتی به نام https://news.example.com را در نظر بگیرید. این سایت میخواهد به منابع API در partner-api.com دسترسی پیدا کند. توسعهدهندگان در https://partner-api.com ابتدا هدرهای اشتراکگذاری منابع متقابل مبدأ (CORS) را در سرور خود با افزودن new.example.com به لیست مبدأهای مجاز پیکربندی میکنند. آنها این کار را با افزودن خط زیر به فایل پیکربندی سرور خود انجام میدهند.
Access-Control-Allow-Origin: https://news.example.com
پس از پیکربندی دسترسی CORS، news.example.com میتواند منابع را از partner-api.com درخواست کند. برای هر درخواست، partner-api.com با Access-Control-Allow-Credentials : “true” پاسخ خواهد داد. سپس مرورگر میداند که ارتباط مجاز است و دسترسی متقابل مبدأ را مجاز میکند.اگر میخواهید دسترسی را به چندین مبدأ اعطا کنید، از یک لیست جدا شده با کاما یا کاراکترهای عام مانند * استفاده کنید که دسترسی را به همه اعطا میکند.
درخواست پیشپرواز CORS چیست؟
در HTTP، متدهای درخواست عملیات دادهای هستند که کلاینت میخواهد سرور انجام دهد. متدهای رایج HTTP شامل GET، POST، PUT و DELETE هستند.در یک تعامل اشتراکگذاری منابع متقابل مبدأ (CORS) معمولی، مرورگر درخواست و هدرهای کنترل دسترسی را همزمان ارسال میکند. اینها معمولاً درخواستهای داده GET هستند و کم خطر در نظر گرفته میشوند.با این حال، برخی از درخواستهای HTTP پیچیده در نظر گرفته میشوند و قبل از ارسال درخواست واقعی به تأیید سرور نیاز دارند. فرآیند پیشتأیید، درخواست پیشپرواز نامیده میشود.
درخواستهای متقابل مبدأ پیچیده
درخواستهای متقابل مبدأ در صورتی پیچیده هستند که از هر یک از موارد زیر استفاده کنند:
- متدهای غیر از GET، POST یا HEAD
- هدرهای غیر از Accept-Language، Accept یا Content-Language
- هدرهای Content-Type غیر از multipart/form-data، application/x-www-form-urlencoded یا text/plain
بنابراین، برای مثال، درخواستها برای حذف یا اصلاح دادههای موجود پیچیده در نظر گرفته میشوند.
درخواستهای پیشپرواز چگونه کار میکنند؟
مرورگرها در صورت نیاز درخواستهای پیشپرواز ایجاد میکنند. این یک درخواست OPTIONS مانند درخواست زیر است.
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE
مرورگر درخواست پیشپرواز را قبل از پیام درخواست واقعی ارسال میکند. سرور باید به درخواست پیشپرواز با اطلاعات مربوط به درخواستهای متقابل مبدأ که سرور مایل به پذیرش از URL کلاینت است، پاسخ دهد. هدرهای پاسخ سرور باید شامل موارد زیر باشد:
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Allow-Origin
پاسخ سرور مثالی در زیر آمده است.
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: https://news.example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS
پاسخ پیشپرواز گاهی اوقات شامل یک هدر اضافی Access-Control-Max-Age است. این متریک مدت زمان (به ثانیه) را برای ذخیره نتایج پیشپرواز در مرورگر مشخص میکند. ذخیرهسازی به مرورگر اجازه میدهد چندین درخواست پیچیده را بین درخواستهای پیشپرواز ارسال کند. نیازی نیست تا زمانی که زمان مشخص شده توسط max-age منقضی شود، درخواست پیشپرواز دیگری ارسال کند.
تفاوت بین CORS و JSONP چیست؟
JSON با پدینگ (JSONP) یک تکنیک تاریخی است که ارتباط بین برنامههای وب در حال اجرا در دامنههای مختلف را امکانپذیر میکند.با JSONP، از تگهای اسکریپت HTML در صفحه کلاینت استفاده میکنید. تگ اسکریپت فایلهای جاوا اسکریپت خارجی را بارگیری میکند یا کد جاوا اسکریپت را مستقیماً در یک صفحه HTML جاسازی میکند.از آنجا که اسکریپتها مشمول سیاست مبدأ یکسان نیستند، میتوانید دادههای متقابل مبدأ را از طریق کد جاوا اسکریپت بازیابی کنید. با این حال، دادهها باید در قالب JSON باشند. همچنین، JSONP نسبت به اشتراکگذاری منابع متقابل مبدأ (CORS) امنیت کمتری دارد زیرا به قابل اعتماد بودن دامنه خارجی برای ارائه دادههای ایمن متکی است. مرورگرهای مدرن برخی ویژگیهای امنیتی را اضافه کردهاند، بنابراین کد قدیمی حاوی JSONP دیگر در آنها کار نخواهد کرد. CORS استاندارد جهانی وب فعلی برای کنترل دسترسی متقابل مبدأ است. درباره جاوا اسکریپت بخوانید » درباره JSON بخوانید »
برخی از بهترین روشهای CORS چیست؟
هنگام پیکربندی اشتراکگذاری منابع متقابل مبدأ (CORS) در سرور خود، باید موارد زیر را در نظر داشته باشید.
تعریف لیستهای دسترسی مناسب
همیشه بهتر است با استفاده از لیستهای جدا شده با کاما، دسترسی را به دامنههای فردی اعطا کنید. از استفاده از کاراکترهای عام خودداری کنید مگر اینکه بخواهید API را عمومی کنید. در غیر این صورت، استفاده از کاراکترهای عام و عبارات منظم ممکن است آسیبپذیری ایجاد کند. برای مثال، فرض کنید یک عبارت منظم مینویسید که دسترسی را به همه سایتهای دارای پسوند permitted-website.com اعطا میکند. با یک عبارت، دسترسی را به api.permitted-website.com و news.permitted-website.com اعطا میکنید. اما ناخواسته دسترسی را به سایتهای غیرمجاز که ممکن است از دامنههایی مانند maliciouspermitted-website.com استفاده کنند، اعطا میکنید.
از استفاده از مبدأ null در لیست خود خودداری کنید
برخی از مرورگرها مقدار null را در هدر درخواست برای سناریوهای خاصی مانند درخواستهای فایل یا درخواستها از میزبان محلی ارسال میکنند. با این حال، نباید مقدار null را در لیست دسترسی خود قرار دهید. همچنین خطرات امنیتی را به همراه دارد زیرا درخواستهای غیرمجاز حاوی هدرهای null ممکن است دسترسی پیدا کنند.