CORS چیست و آموزش رفع خطاهای مربوط به آن در مرورگرها؟
در زمانهای قدیم، وب سایتها با تمام منابعشان در یک جا هاست میشدند و از همانجا نیز فراخوانی میشدند. اما با گذشت زمان و پیشرفتهای چشمگیر در این حوزه، این روش دیگر امکان استفاده، حداقل برای بسیاری از سایتهای بزرگ، نداشت. اکنون هر کدام از منابع ممکن است از یکجا خوانده شوند. مثلاً عکسها از یکجا فراخوانی شود و فیلمها از جای دیگر. این موضوع ممکن است مشکلات بسیار زیاد امنیتی ایجاد نماید. به همین دلیل باید قوانینی برای آن به وجود میآمد که مرورگرهای سمت کاربر، به طور کلی اقدام به بستن هر درخواستی به بیرون را نکنند. این قوانین تحت نامی با عنوان CORS شکل گرفت. در ادامه با اکتوبیت همراه باشید تا به بررسی بیشتر آن بپردازیم.
فهرست مطالب
CORS چیست؟
CORS که مخفف Cross-Origin Resource Sharing میباشد، به مجموعهای از سیاستها در مرورگرهای وب اطلاق میشود که به وبسایتها امکان میدهد منابع را با دامنههای متفاوت درخواست کنند. در واقع، CORS به وبسایتها اجازه میدهد درخواستهای HTTP را از دامنههای دیگر دریافت کنند.
محدودیتهای امنیتی CORS به دلیل سیاست همگامسازی سراسری وجود دارد. بدون سیاستهای CORS، مرورگرها مانعی جدی ایجاد میکنند تا وبسایتها از دامنههای دیگر درخواست دریافت کنند و به منابعی مثل فایلهای جاوا اسکریپت، فونتها، تصاویر و غیره دسترسی پیدا کنند.
با استفاده از سیاستهای CORS، سرور وب میتواند اطمینان حاصل کند که درخواستها فقط از دامنههای معتبری صادر میشوند و تجاوزات امنیتی محدود شوند. سرور وب میتواند سیاستهای CORS را به عنوان هدر در پاسخهای HTTP در اختیار مرورگر قرار دهد تا مشخص کند کدام منابع و انواع درخواستها مجاز هستند.
به طور خلاصه، CORS اجازه میدهد تا وبسایتها از دامنههای دیگر درخواست کرده و منابع مورد نیاز را دریافت کنند، اما با محدودیتهای امنیتی تعیین شده توسط سرور وب.
هدرهای CORS
مهمترین هدرهایی که در رابطه با CORS وجود دارند، عبارتند از:
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Timing-Allow-Origin
تفاوت Same Origin و Cross Origin
Same Origin و Cross Origin دو مفهوم مهم در محیط وب هستند و به نحوه تعامل میان منابع مختلف در مرورگرها مربوط میشوند. تفاوت اصلی بین آنها به دامنههای مورد نظر میان منابع مربوط است که درخواست میشود.
- Same Origin: این مفهوم به معنای دامنه یا پروتکل و پورت مشترک در مرورگر است. اگر دو منبع (مانند اسکریپت جاوااسکریپت و صفحه وب) از یک دامنه، پروتکل و پورت مشابه درخواست میکنند، آنها به عنوان Same Origin شناخته میشوند. در اصل same origin، درخواستهای از منابع یکسان، بدون محدودیت امنیتی در مرورگر اجرا میشوند و دسترسی به منابع مشابه به راحتی صورت میگیرد.
- Cross Origin: این مفهوم به معنای تفاوت در دامنه، پروتکل یا پورت بین منابع است. اگر یک منبع، درخواستی را از دامنه، پروتکل یا پورت متفاوتی ارسال کند، آنها به عنوان Cross Origin شناخته میشوند. در اصل cross origin، به دلایل امنیتی، مرورگرها محدودیتهایی برای دسترسی به منابع Cross Origin اعمال میکنند. این محدودیتها شامل سیاستهای CORS میشوند که تعیین میکنند کدام منابع Cross Origin مجاز به دسترسی هستند و کدام منابع باید از دسترسی محدود شوند.
در کل، Same Origin و Cross Origin تعیین کنندهٔ نحوه ارتباط منابع در محیط وب هستند، که تحت تأثیر سیاستهای امنیتی مشخصی قرار میگیرند.
قوانین same-origin، یک سری موارد امنیتی برای جلوگیری از جعل درخواست بین سایتی (CSRF) هستند. بدون این قانون، یک وبسایت مخرب میتواند با ارسال درخواست HTTP، اطلاعات حساس شما را در وبسایت دیگری بخواند. قوانین same-origin، فقط اسکریپتهای موجود در صفحه را از دسترسی به دادهها یا ارسال دادهها به منبعی دیگر، منع میکنند. اطلاعات دیگر مانند فایلهای تصاویر و یا CSS، محدودیتی ندارند و از منابع دیگر در دسترس خواهند بود. برای دسترسی به دادهها از منابع دیگر یا ارسال داده به آنها، CORS مورد نیاز است.
تفاوت Same Origin و Strict Origin
تفاوت بین Same Origin و Strict Origin در واقع در سطح سختی اجرای سیاست Same-Origin (سیاست هم منبع) است. این سیاست توسط مرورگرهای وب برای محدود کردن تعاملات بین منابع مختلف اجرا میشود و سطح سختی در اجرای آن به صورت زیر است:
۱. Same Origin: این قانون به معنای این است که دو منبع (مانند کد جاوااسکریپت و صفحه وب) همان منبع را دارند، به این معنی که آنها دامنه، پروتکل و پورت یکسانی را به اشتراک میگذارند. در زمینه سیاست هم منبع، وقتی منابع یکی باشند، بدون هیچ محدودیت ایمنی مرورگر، میتوانند به طور آزاد با یکدیگر تعامل کنند. Same Origin به منابع با منابع مشابه اجازه دسترسی بدون محدودیت میدهد.
۲. Strict Origin: این قانون نوعی سختگیری بیشتر در سیاست Same-Origin است. علاوه بر اشتراک دامنه، پروتکل و پورت، منابع باید دقیقاً همان اسکیما را داشته باشند. اسکیما به پیشوند URL مربوط میشود، مانند “http://” یا “https://”. در Strict Origin، اگر اسکیمای بین منابع متفاوت باشد، آنها به عنوان منابعی مجزا در نظر گرفته میشوند و تحت محدودیتهای سیاست Same-Origin قرار میگیرند. این سختگیری بیشتر به منظور ارائه امنیت بیشتر است.
به طور خلاصه، سیاست Same-Origin به منابع با دامنه، پروتکل و پورت یکسان اجازه تعامل بدون هیچ محدودیتی را میدهد، در حالی که Strict Origin با اجبار تطابق طرح (پیشوند URL) نیز، محدودیتهای اضافی را اعمال میکند. Strict Origin با توجه به تطابق دقیق طرح URL، سطحی بالاتر از امنیت را فراهم میکند و حتی تفاوتهای کوچک در طرح را به عنوان منابع جداگانه با محدودیتهای سیاست در نظر میگیرد.
چرا خطای CORS رخ می دهد؟
CORS از درخواستها و انتقال دادهها بین مرورگرها و سرورهای cross-origin پشتیبانی میکند تا به صورت ایمن انجام شوند. همچنین متکی به مکانیزمی است که بررسی میکند آیا سرور نیز به درخواستهای منابع دیگر اجازه اجرا میدهد یا خیر، تا از ایمنی درخواستهای cross-origin مطمئن شود.
در واقع خطای CORS زمانی رخ میدهد که درخواستی از یک منبع Cross Origin (از دامنه، پروتکل یا پورت متفاوت) به منبع هدف صورت گیرد و سیاستهای CORS این درخواست را محدود میکنند. برخی از دلایل رایج برای بروز خطای CORS عبارتند از:
- سیاستهای CORS نادرست: سرور مقصد درخواستها را با سیاستهای CORS نادرست تنظیم کرده است. برای مثال، سرور مقصد ممکن است هیچ هدر CORS در پاسخهای HTTP خود قرار ندهد یا سیاستهای CORS را به طور نادرست پیکربندی کند که منابع Cross Origin را محدود میکند.
- عدم مجاز بودن دامنه منبع: سرور مقصد ممکن است دامنه منبع درخواست را در لیست سفید (allowed origins) قرار ندهد. در نتیجه، مرورگر از ارسال درخواست جلوگیری میکند و خطای CORS را برمیگرداند.
- روشهای HTTP غیرمجاز: ممکن است سرور مقصد تنها روشهای HTTP معتبر را برای درخواستها مجاز بداند، ولی درخواست از روش غیرمجازی (مانند PUT یا DELETE) صورت گرفته است.
- توکنهای امنیتی: اگر سیستم احراز هویت و دسترسی با توکنهای امنیتی (مانند JWT) استفاده میشود، ممکن است توکنهای درخواست از دامنههای دیگر را در سیاستهای CORS ثبت نکرده باشید. این باعث میشود که مرورگر از دسترسی درخواست متوقف شود و خطای CORS را برگرداند.
- سیاستهای CORS در مرورگر: بعضی از مرورگرها ممکن است سیاستهای CORS خود را به طور مشخص تنظیم کرده باشند که باعث محدودیت دسترسی به منابع Cross Origin میشود.
برای رفع خطای CORS، شما باید سیاستهای CORS را در سرور مقصد به درستی پیکربندی کنید، دامنه منبع را به لیست سفید اضافه کنید و معتبر بودن روشهای HTTP و توکنهای امنیتی را بررسی کنید. همچنین، ممکن است نیاز باشد تنظیماتی در مرورگر خود برای پشتیبانی از CORS انجام دهید.
خطای CORS در رابطه با API
خطای CORS برای اتصال به یک API، یکی از رایجترین خطاهایی است که احتمالاً بسیاری از برنامه نویسان با آن مواجه شدهاند.
دو URL زمانی که پروتکلها، پورتها یا میزبانهای متفاوتی داشته باشند، منبع (Origin) متفاوتی نیز خواهند داشت.
برای نمونه، ارسال درخواست از https://actobit.com به https://api.actobit.com به عنوان cross-origin در نظر گرفته میشود زیرا نامهای میزبان متفاوتی دارند.
مرورگرها از قوانین same-origin پیروی کرده و درخواستهای HTTP با cross-origin را که از اسکریپتها ارسال میشوند، محدود میکنند. این یعنی که یک وب سایت فقط مجاز به ارسال درخواست از منبع متعلق به خود است، مگر اینکه ارجاعات مرتبط با منابع دیگر، شامل هدرهای CORS مناسب باشند.
نحوه رفع خطای CORS
راه حل ۱: Backend را برای ارائه دسترسی به CORS، پیکربندی کنید
اگر به Backend سایت خود دسترسی دارید، میتوانید آن را به گونهای پیکربندی نمایید که درخواستهای CORS را در صورت مجاز بودن، انجام دهد. شرط اساسی این است که Access-Control-Allow-Origin را به هدر پاسخ اضافه کنید تا منبعی که اجازه دسترسی به منابع سرور را دارد، مشخص نمایید. میتوانید Backend را طوری پیکربندی کنید که مقدار زیر را در هدر پاسخ بازگرداند:
Access-Control-Allow-Origin: https://api.actobit.com
این کد به https://api.actobit.com اجازه میدهد تا یک درخواست cross-origin به سرور شما ارسال کند. با این حال، فقط میتوان یک منبع اضافه کرد. اگر میخواهید چندین منبع را مجاز کنید، میتوانید با خواندن هدر Origin از درخواست، مقدار آن را به صورت پویا و با مقدار Access-Control-Allow-Origin تنظیم کنید.
روش دیگر، تنظیم هدر روی * : Access-Control-Allow-Origin برای اجازه دسترسی به درخواستهای دریافتی از تمامی URL ها است. با این حال، هنگام استفاده از آن باید مراقب باشید زیرا ممکن است سرور شما را در برابر حملات CSRF آسیب پذیر کند.
راه حل ۲: از یک سرور پروکسی استفاده کنید
از آنجایی که قوانین یکسانی توسط مرورگرهای اینترنتی اجرا میشوند اما در ارتباط سرور به سرور اینگونه نیست، میتوانید از یک سرور پروکسی برای فراخوانی API خارجی استفاده کنید.
یک سرور پروکسی به عنوان یک میان افزار (middleware) بین سیستم کاربر و سرور عمل میکند. به جای ارسال درخواست مستقیم از سیستم کاربر به API خارجی، میتوانید درخواست را به سرور پروکسی ارسال کنید. سرور پروکسی، یک درخواست به API خارجی به جای شما ارسال کرده و پاسخی را که از API خارجی دریافت میکند، برمیگرداند.
اگر سرور API خارجی، هدرهای HTTP مطابق با استاندارد CORS را برنگرداند، خطای CORS رخ میدهد. میتوانید هدر از دست رفتهای مانند * : Access-Control-Allow-Origin را به درخواست اضافه کنید و پاسخ را با استفاده از یک سرور پروکسی، به مرورگر برگردانید.
پس در برخی موارد، میتوانید از یک Proxy Server مانند Nginx به عنوان واسطهای بین مرورگر و سرور مقصد استفاده کنید. با پیکربندی مناسب Proxy Server، میتوانید محدودیتهای CORS را درخواستهایی که به سرور مقصد ارسال میشوند، برطرف کنید.
جمعبندی
CORS یک مکانیسم HTTP است که امکان اشتراکگذاری اطلاعات بین یک منبع با منبع دیگر را به صورت امن فراهم میکند. مهمترین قسمت در رفع خطای CORS، پیکربندی درست سرور مقصد است. بهتر است مستندات مربوط به سرور مورد استفاده خود را بررسی کنید و روش مناسب برای تنظیم سیاستهای CORS را در آن پیادهسازی کنید.