CORS چیست؟
فهرست مطالب
- CORS چیست؟
- چگونه کار می کند؟
- چگونه کار می کند؟
- پیش پرواز CORS چیست؟
- هدرهای CORS
- چرا درخواست ها توسط خط مشی CORS مسدود می شوند؟
- چگونه خطای CORS را برطرف کنیم؟
- 1. سرور خود را پیکربندی کنید
- 2. افزونه مرورگر را نصب کنید
- 3. بررسی های CORS توسط مرورگر را غیرفعال کنید
- 4. یک سرور پروکسی راه اندازی کنید
- چگونه CORS را آزمایش کنیم؟
- مراقب خطاهای نادرست CORS باشید
- نتیجه گیری
- منابع
CORS چیست؟
Cross-Origin Resource Sharing (CORS) یک مکانیسم امنیتی مبتنی بر HTTP است که توسط سیستم کلاینت (مرورگر وب کاربر) کنترل و اجرا می شود. CORS به یک سرویس (API) اجازه می دهد تا هر منبع دیگری غیر از خودش را که مشتری می تواند از آن منابع درخواست داده کند را مشخص کند. CORS در پاسخ به سیاست هم مبدأ بودن یا سیاست same-origin policy (SOP) طراحی شده است که نحوه تعامل وب سایت (سند HTML یا اسکریپت JS) توسط یک مبدا را با منبعی از مبدا دیگر محدود می کند. CORS برای اجازه دادن صریح به برخی از درخواستهای متقاطع و رد کردن سایر درخواستها استفاده میشود.
CORS اساساً در مرورگرهای وب پیادهسازی میشود، اما میتوان از آن در کلاینتهای API به عنوان یک گزینه قابل پیاده سازی نیز استفاده کرد. CORS در همه مرورگرهای محبوب اینترنتی مانند گوگل کروم، فایرفاکس، اپرا و سافاری وجود دارد. این استاندارد در ژانویه 2014 به عنوان یک توصیه از طرف W3C پذیرفته شده است. بر اساس آن، می توانیم فرض کنیم که سیاست CORS در تمام مرورگرهای اینترنتی موجود و دیگر مرورگرها در حال حاضر پیاده سازی شده است.
CORS چگونه کار می کند؟
همه چیز از سمت کلاینت شروع می شود، و آن هم قبل از ارسال درخواست اصلی. کلاینت یک درخواست پیش از پرواز CORS را برای منابعی با پارامترهایی در هدرهای HTTP (هدرهای CORS) به یک سرور ارسال می کند. سرور یا سرویس دهنده، پاسخی با هدرهای یکسان اما با مقادیر متفاوت یا اساسا پاسخی با هدرهای یکسان ارائه می دهد. کلاینت بر اساس پاسخ CORS قبل از پرواز تصمیم می گیرد که آیا می تواند درخواست اصلی خود را به سرویس ارسال کند یا خیر. اگر پاسخ با الزامات CORS پیش از پرواز مطابقت نداشته باشد، مرورگر وب (کاربر) با خطا مواجه می شود.
درخواستهای پیش از پرواز CORS بدون توجه به اینکه چه کتابخانهها یا فریم ورکهایی برای ارسال درخواستها مورد استفاده قرار گرفته اند، از مرورگر وب ارسال میشوند. به همین دلیل است که هنگام کار با API از برنامه بک اند خود، نیازی به مطابقت با الزامات CORS ندارید.
پیش پرواز CORS چیست؟
هنگامی که یک مرورگر درخواستی را به یک سرور ارسال می کند، ابتدا یک درخواست برای دریافت گزینه های ارسال به نام HTTP Options Request ارسال می کند. این درخواست پیش از پرواز CORS نامیده می شود. سپس سرور با لیستی از متدها و هدرهای مجاز پاسخ می دهد. اگر مرورگر مجاز به درخواست اصلی باشد، درخواست اصلی را ارسال می کند. اگر نه، خطا نشان می دهد و به ارسال درخواست اصلی ادامه نمی دهد.
هدرهای CORS
هدرهای CORS هدرهای HTTP معمولی هستند که برای کنترل خط مشی CORS استفاده می شوند. آنها در درخواست هایی استفاده می شوند که در آن مرورگر یک درخواست پیش از پرواز CORS را به سرور ارسال می کند و سرور با موارد زیر پاسخ می دهد:
- Access-Control-Allow-Origin نشان می دهد که چه مبدایی می تواند منابع را واکشی کند. از یک یا چند منبع استفاده کنید، به عنوان مثال: https://foo.io, http://bar.io.
- Access-Control-Allow-Methods نشان می دهد که چه روش های HTTP مجاز هستند. از یک یا چند متد HTTP با کاما استفاده کنید، به عنوان مثال: GET,PUT,POST.
- Access-Control-Allow-Headers نشان می دهد که چه عنوان های درخواستی مجاز است. از یک یا چند هدر استفاده کنید، به عنوان مثال: Authorization,X-My-Token.
- Access-Control-Allow-Credentials نشان می دهد که آیا ارسال کوکی ها مجاز است یا خیر. پیش فرض: مجاز نیست.
- Access-Control-Max-Age - نشان می دهد که نتیجه درخواست چه مدت باید در حافظه پنهان بماند، برحسب ثانیه. پیش فرض: 0 ثانیه.
اگر تصمیم دارید از Access-Control-Allow-Credentials=true استفاده کنید، پس باید از این واقعیت آگاه باشید که نمی توانید از علامت های عام * در هدرهای Access-Control-Allow-* استفاده کنید. لازم است به صراحت تمام مبداها، متدها و هدرهای مجاز فهرست شوند.
لیست کامل هدرهای CORS را ببینید.
چرا یک درخواست توسط خط مشی CORS مسدود می شود؟
اگر یک توسعه دهنده وب هستید، احتمالا قبلا خطاهای CORS را دیده یا شنیده اید و بارها برای یافتن راه حل آن، در گوگل جستجو کرده اید. رایج ترین مشکل این است که مرورگر درخواست را به دلیل سیاست CORS مسدود می کند. مرورگر یک خطایی ایجاد می کند و یک گزارش در کنسول نشان می دهد:
خطای CORS بالا به کاربر اطلاع میدهد که مرورگر نمیتواند به منبعی (https://localhost:8080) از مبدأ (https://localhost:3000) دسترسی پیدا کند زیرا سرور اجازه نمی دهد. این اتفاق به این دلیل افتاده است که سرور با سربرگ Access-Control-Allow-Origin با مبدأ یا با علامت * در پاسخ CORS قبل از پرواز پاسخ نداده است.
یک درخواست ممکن است توسط خط مشی CORS مسدود شود نه تنها به دلیل منشاء آن نادرست است، بلکه همچنین به یکی از دلایل دیگر نظیر نادرست بودن هدر HTTP، متد HTTP یا هدر کوکی.
چگونه خطای CORS را برطرف کنیم؟
ایده اساسی "اصلاح CORS" این است که به درخواست های "OPTIONS" ارسال شده از یک کلاینت با هدرهای مناسب پاسخ دهید. راه های زیادی برای شروع پاسخگویی با CORS مناسب وجود دارد. می توانید از سرور پروکسی استفاده کنید یا می توانید از نرم افزارهای واسط در سرور خود استفاده کنید.
به یاد داشته باشید که هدرهای Access-Control-* در یک مرورگر وب با توجه به مقدار تنظیم شده در هدر Access-Control-Max-Age ذخیره می شوند. لطفا قبل از آزمایش تغییرات، حافظه پنهان مرورگر را پاک کنید. همچنین می توانید کش را در مرورگر خود غیرفعال کنید.
1. سرور خود را پیکربندی کنید
به طور پیش فرض، اگر صاحب سرور هستید، باید پاسخ های CORS را در سرور خود پیکربندی کنید و این تنها راه حل صحیح مشکل است. شما می توانید به روش های مختلف و در چندین لایه از برنامه خود به این امر دست یابید. رایج ترین راه استفاده از پروکسی معکوس، دروازه API یا هر سرویس مسیریابی دیگری است که اضافه کردن هدر به پاسخ ها را ارائه می دهد. سرویس های زیادی وجود دارد که می توانید برای این کار از آنها استفاده کنید، برخی از آنها عبارتند از: HAProxy، Linkerd، Istio، Kong، nginx، Apache، Traefik. اگر زیرساخت شما فقط شامل یک برنامه بدون هیچ لایه اضافی است، می توانید به سادگی پشتیبانی CORS را در کد برنامه خود اضافه کنید.
در اینجا چند نمونه از فعال کردن CORS آورده شده است:
- Apache: با تغییر فایل .htaccess،
- Nginx: با تغییر فایل پیکربندی،
- Traefik: با استفاده از نرم افزارهای واسط،
- Spring Boot: با استفاده از از حاشیه نویسی @EnableCORS،
- ExpressJS: با استفاده از app.use(cors())
- NextJS: با استفاده از راهنماهای درخواست.
در این سایت می توانید نمونه های بیشتری از فعال کردن CORS در فریم ورک ها و زبان های مختلف پیدا کنید: enable-cors.org.
اگر نمی توانید CORS را در سرور مورد نظر خود فعال کنید، اما همچنان می خواهید به آن درخواست بدهید، باید از یکی از راه حل های زیر استفاده کنید.
2. یک افزونه مرورگر برای این کار نصب کنید
استفاده از افزونه مرورگر ممکن است راهی سریع و آسان برای حل مشکلات شما با CORS در محیط برنامه نویسی شما باشد. بزرگترین مزیت استفاده از افزونه های مرورگر این است که نیازی به تغییر کد یا پیکربندی ندارید. از طرف دیگر، شما باید یک افزونه را روی هر مرورگر وب که برای آزمایش برنامه وب خود استفاده می کنید، نصب کنید.
اکستنشن های مرورگر با افزودن هدرهای لازم برای فریب مرورگر، درخواست قبل از پرواز ورودی را تغییر می دهند. این یک راه حل مفید برای کار به صورت لوکال با APIهایی است که درخواست ها را فقط می توانند از دامنه اصلی خود بپذیرند.
میتوانید برنامههای افزودنی را در فروشگاه وب گوگل یا در کتابخانه افزونههای موزیلا پیدا کنید. در برخی موارد، پیکربندی برنامه افزودنی پیش فرض ممکن است کافی نباشد. مطمئن شوید که افزونه نصب شده به درستی پیکربندی شده است. همچنین باید توجه داشته باشید که روشن ماندن برنامه افزودنی به طور نامحدود ممکن است در برخی از وب سایت ها مشکل ایجاد کند. استفاده از آنها فقط برای اهداف توسعه و برنامه نویسی توصیه می شود.
3. بررسی های CORS مرورگر را غیرفعال کنید
می توانید بررسی های CORS را در مرورگر خود به طور کامل غیرفعال کنید. برای غیرفعال کردن بررسیهای CORS در گوگل کروم، باید مرورگر را ببندید و آن را با فلگهای --disable-web-security و --user-data-dir اجرا کنید. با انجام این کار، گوگل کروم درخواستهای پیش از پرواز CORS را ارسال نمیکند و هدرهای CORS را تأیید نمیکند.
# macOS open /Applications/Google\ Chrome.app --args --user-data-dir="/var/tmp/chrome-dev-disabled-security" --disable-web-security --disable-site-isolation-trials
# Linux google-chrome --user-data-dir="~/chrome-dev-disabled-security" --disable-web-security --disable-site-isolation-trials
همه این دستورات بالا گوگل کروم را در یک جعبه ایمنی ایزوله راه اندازی می کنند. این دستورات بر پروفایل اصلی کروم شما تأثیری نمی گذارند.
فهرست همه فلگهای موجود برای گوگل کروم را می توانید اینجا مشاهده کنید.
4. یک سرور پراکسی راه اندازی کنید
اگر به دنبال راه حلی هستید که نیازی به تغییر تنظیمات مرورگر نداشته باشد، باید به راه حل سرور پروکسی نگاهی بیاندازید. این گزینه به شما کمک می کند تا بدون تغییر چیزی در مرورگر خود، بر خطاهای CORS غلبه کنید. ایده استفاده از سرور پروکسی این است که تمام درخواست ها را به سرور پراکسی خود ارسال کنید و سپس سرور پراکسی، درخواست را به سرویس واقعی که می خواهید استفاده کنید ارسال کند. شما می توانید یک سرور پراکسی را برای خود به تنهایی به زبان و فریمورک دلخواه خود بسازید. شما باید CORS را پیکربندی کنید و یک عملکرد را برای ارسال درخواست های دریافت شده به سرویس دیگری پیاده سازی کنید.
اگر به سرویسی که قصد استفاده از آن را دارید دسترسی ندارید، سرور پروکسی راه حل خوبی است. سرویسهای سرور پراکسی منبع باز و آماده برای استفاده وجود دارد، اما همیشه باید اطمینان حاصل کنید که آنها سعی نکنند مداخله ای در مجوزهای درخواستهای شما ایجاد کنند و یا اطلاعات را رهگیری کنند و آنها را به سرویسهای شخص ثالث منتقل کنند. چنین نقض های امنیتی می تواند شکست فاجعه بار برای شما و کاربران بالقوه سرویس شما به وجود آورد.
فهرست خدمات CORS منبع باز که می توانید در اینترنت پیدا کنید:
- https://github.com/Freeboard/thingproxy
- https://github.com/bulletmark/corsproxy
- https://github.com/Rob--W/cors-anywhere
لطفا قبل از استفاده از هر یک از خدمات فوق، از جدیدترین نسخه های موجود استفاده کنید.
چگونه CORS را آزمایش کنیم؟
استفاده از مرورگر برای آزمایش پیکربندی CORS ممکن است کاری خسته کننده باشد. می توانید از ابزاری مانند CORS Tester، test-cors.org استفاده کنید، یا اگر با خط فرمان آشنا هستید، می توانید از curl برای آزمایش پیکربندی CORS خود استفاده کنید.
مراقب خطاهای نادرست CORS باشید
در برخی موارد، هنگامی که یک سرویس در پشت یک لایه اضافی با ابزارهایی نظیر محدود کننده نرخ، متعادل کننده بار یا سرور مجوز قرار می گیرد، در این صورت می توانید یک خطای CORS کاذب دریافت کنید. درخواستهای مسدود یا رد شده توسط سرور باید با یک کد وضعیت خطا دریافت شوند. به عنوان مثال.،:
- 401 unauthorized,
- 403 forbidden,
- 429 too many requests,
- 500 internal server error,
- یا کدهایی غیر از 2XX یا 3XX.
ممکن است مشاهده کنید که درخواست به دلیل عدم موفقیت درخواست قبل از پرواز مسدود شده است، اما در واقع، سرور آن را رد می کند. همیشه باید کد وضعیت و بدنه پاسخ را بررسی کنید تا از اشکال زدایی غیر ضروری جلوگیری کنید. مرورگر به درستی به شما هشدار می دهد که درخواست CORS قبل از پرواز با شکست مواجه شده است، اما دلیل شکست لزوما به پیکربندی CORS مرتبط نیست.
نتیجه گیری
در این مقاله سعی کردیم توضیح دهیم CORS چیست و رایج ترین مشکلات آن چه چیزی می باشند. ما 4 راه برای رفع مشکلات CORS پیشنهاد دادیم و مزایا و معایب هر کدام را توضیح دادیم. همچنین توضیح دادیم که چگونه پاسخ های CORS را به درستی پیکربندی کنیم و چگونه آنها را آزمایش کنیم. علاوه بر این، ما نشان دادیم که رایج ترین مسائل مربوط به تشخیص خطاهای نادرست CORS چیست. سعی کردیم همه چیز را به زبان ساده بیان کنیم و از نکات ظریف فنی اجتناب کنیم. اگر سوالی، ابهامی یا پیشنهادی دارید، لطفا با ما از طریق بخش نظرات در میان بگذارید.