درک نحوه عملکرد CORS در مرورگرهای وب

اشتراکگذاری منابع متقاطع (CORS) یک ویژگی امنیتی حیاتی در مرورگرهای وب است که نحوه درخواست منابع (مانند دادهها، تصاویر، یا اسکریپتها) توسط برنامههای کاربردی وب را از دامنهای متفاوت از دامنهای که در صفحه وب اولیه ارائه میشود، کنترل میکند. در اصل برای محافظت از کاربران در برابر سایت های مخربی طراحی شده است که سعی در دسترسی به اطلاعات حساس در سایر وب سایت ها دارند. این وبلاگ توضیح خواهد داد که CORS چگونه کار می کند و چرا برای توسعه وب بسیار مهم است.
CORS چیست؟
به زبان ساده، CORS یک مکانیسم مرورگر است که کنترل می کند یک صفحه وب چه منابعی را می تواند از دامنه های مختلف درخواست کند. به طور پیشفرض، مرورگرها سیاست همان مبدأ (SOP) را پیادهسازی میکنند که صفحات وب را از درخواست به دامنهای غیر از دامنهای که صفحه از آن بارگذاری شده است، محدود میکند. این سیاست یک ویژگی امنیتی اساسی است که از تعاملات احتمالی مضر بین وب سایت ها جلوگیری می کند.
با این حال، موارد زیادی وجود دارد که درخواستهای متقاطع قانونی ضروری هستند – برای مثال، زمانی که یک برنامه وب نیاز به واکشی دادهها از یک API میزبانی شده در سرور دیگری دارد. CORS با اجازه دادن به سرورها برای تعیین اینکه کدام دامنه ها مجاز به دسترسی به منابع خود هستند، چنین درخواست هایی را به روشی ایمن فعال می کند.
CORS چگونه کار می کند؟
CORS با افزودن سرصفحههای HTTP به پاسخهای یک سرور کار میکند و نشان میدهد که آیا درخواست متقاطع مجاز است یا خیر. در اینجا یک تفکیک گام به گام از نحوه عملکرد CORS آورده شده است:
مشتری یک درخواست می کند
هنگامی که یک صفحه وب سعی میکند درخواستی (مثلاً از طریق XMLHttpRequest، واکشی، یا گنجاندن اسکریپت) به مبدأ متفاوتی (تعریف شده توسط دامنه، پروتکل و پورت) ارسال کند، مرورگر بررسی میکند که آیا درخواست خطمشی همان مبدأ را نقض میکند یا خیر.
درخواست پیش از پرواز CORS (برای درخواست های پیچیده)
برخی از درخواستها، بهویژه آنهایی که با روشهایی مانند PUT، DELETE یا با هدرهای سفارشی هستند، «پیچیده» در نظر گرفته میشوند. قبل از ارسال درخواست واقعی، مرورگر یک درخواست OPTIONS ارسال می کند که به عنوان درخواست پیش از پرواز شناخته می شود. این درخواست پیش از پرواز از سرور میپرسد که آیا درخواست واقعی را مجاز میکند یا نه و روشها، سرصفحهها و مبداهای مجاز HTTP را تأیید میکند.
سرور با هدرهای CORS پاسخ می دهد
سروری که درخواست پیش از پرواز یا واقعی را دریافت می کند، پاسخی را با هدرهای خاص که نشان می دهد درخواست مجاز است یا خیر، پس می فرستد. سرفصل های کلیدی عبارتند از:
Access-Control-Allow-Origin: این هدر مشخص می کند که کدام دامنه ها مجاز به دسترسی به منبع هستند. اگر این هدر شامل مبدا درخواست باشد، مرورگر پاسخ را اجازه می دهد. به عنوان مثال، سرور ممکن است با:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: این هدر مشخص می کند که کدام روش های HTTP (GET، POST، PUT و غیره) سرور اجازه درخواست های متقاطع را می دهد.
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: مشخص می کند که کدام سرصفحه های سفارشی می توانند در درخواست واقعی گنجانده شوند.
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: اگر سرور به اعتبارنامه ها (کوکی ها، احراز هویت HTTP) اجازه دهد، این هدر گنجانده شده و روی درست تنظیم می شود.
مرورگر تصمیم می گیرد
پس از دریافت پاسخ سرور، مرورگر هدرها را ارزیابی می کند. اگر سرور از طریق هدرهای CORS مناسب اجازه دهد، مرورگر درخواست مبدا متقاطع را اجازه می دهد و پاسخ را پردازش می کند. در غیر این صورت، مرورگر درخواست را مسدود می کند و صفحه وب قادر به دسترسی به منبع نیست.
نمونه ای از یک درخواست CORS ساده
سناریویی را در نظر بگیرید که در آن یک صفحه وب میزبانی شده در https://example.com تلاش می کند یک درخواست GET به یک API میزبانی شده در https://api.example.com/data ارسال کند.
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
در این حالت، مرورگر درخواست را به https://api.example.com ارسال می کند. اگر سرور API طوری پیکربندی شده باشد که به درخواستهای https://example.com اجازه دهد، با هدر پاسخ میدهد:
Access-Control-Allow-Origin: https://example.com
اگر هدر وجود نداشته باشد یا نادرست باشد، مرورگر پاسخ را به دلیل خط مشی CORS مسدود می کند.
CORS قبل از پرواز مثال
برای درخواستهای پیچیدهتر، مرورگر یک درخواست قبل از پرواز را آغاز میکند تا بررسی کند که آیا درخواست متقاطع مجاز است یا خیر. در اینجا نمونه ای از درخواست PUT است که یک پیش پرواز را راه اندازی می کند:
fetch('https://api.example.com/update', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'value' })
});
مرورگر یک درخواست OPTIONS را ارسال می کند:
OPTIONS /update HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
سرور باید با هدرهایی پاسخ دهد که نشان دهد آیا این درخواست مجاز است یا خیر:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: Content-Type
اگر این هدرها موجود و معتبر باشند، مرورگر درخواست PUT واقعی را انجام می دهد.
اهمیت CORS
CORS یک ویژگی امنیتی است که مکانیزم دقیقی را برای سرورهای وب برای کنترل دسترسی به منابع خود فراهم می کند. بدون CORS، وبسایتهای مخرب میتوانند به راحتی دادههای حساس را از دامنههای دیگر و بدون رضایت کاربر واکشی کنند که منجر به آسیبپذیریهای امنیتی مانند جعل درخواست متقابل سایت (CSRF) میشود.
نتیجه گیری
درک CORS برای توسعه دهندگان وب که با API ها و منابع شخص ثالث کار می کنند ضروری است. با پیکربندی خطمشیهای CORS مناسب روی سرورها، توسعهدهندگان میتوانند اطمینان حاصل کنند که برنامههای کاربردی آنها امن باقی میمانند و در عین حال تعاملات متقابل مشروع را فعال میکنند.
اگر در حال توسعه یک برنامه وب هستید و با خطاهای CORS روبرو می شوید، ضروری است که پیکربندی سرور را بررسی کنید و از ارسال هدرهای لازم در پاسخ اطمینان حاصل کنید.