مروری بر CORS
پیش از اینکه وارد کدنویسی شویم یا درباره درخواستهای cross-origin بهطور خاص صحبت کنیم، بگذارید لحظهای وقت بگذاریم و تعریف کنیم که منظورمان از اصطلاح origin چیست.
بهطور کلی، اگر دو URL دارای scheme، host و port (اگر مشخص شده باشد) یکسانی باشند، گفته میشود که دارای origin یکسانی هستند. برای درک بهتر این موضوع، بیایید URLهای زیر را مقایسه کنیم:
| URL A | URL B | یکسان هستند؟ | دلیل |
|---|---|---|---|
https://foo.com/a |
http://foo.com/a |
خیر | scheme متفاوت (http در مقابل https) |
http://foo.com/a |
http://www.foo.com/a |
خیر | host متفاوت (foo.com در مقابل www.foo.com) |
http://foo.com/a |
http://foo.com:443/a |
خیر | port متفاوت (بدون port در مقابل 443) |
http://foo.com/a |
http://foo.com/b |
بله | فقط path متفاوت است |
http://foo.com/a |
http://foo.com/a?b=c |
بله | فقط query string متفاوت است |
http://foo.com/a#b |
http://foo.com/a#c |
بله | فقط fragment متفاوت است |
درک اینکه originها چیستند مهم است زیرا تمام مرورگرهای وب مکانیزم امنیتی به نام same-origin policy را پیادهسازی میکنند. تفاوتهای بسیار کوچکی در نحوه پیادهسازی این سیاست توسط مرورگرها وجود دارد، اما بهطور کلی:
یک صفحه وب در یک origin میتواند انواع خاصی از منابع را از origin دیگر در HTML خود جاسازی کند — از جمله تصاویر، CSS و فایلهای JavaScript. بهعنوان مثال، انجام این کار در صفحه وب شما مجاز است:
<img src="http://anotherorigin.com/example.png" alt="example image">
یک صفحه وب در یک origin میتواند دادهها را به origin دیگری ارسال کند. بهعنوان مثال، ارسال دادهها از یک فرم HTML در یک صفحه وب به origin دیگر مجاز است.
اما یک صفحه وب در یک origin اجازه خواندن دادهها از origin دیگر را ندارد.
نکته کلیدی اینجا مورد آخر است: سیاست same-origin از خواندن اطلاعات (احتمالاً محرمانه) وبسایت شما توسط یک وبسایت (احتمالاً مخرب) در origin دیگر جلوگیری میکند.
تأکید بر این نکته مهم است که ارسال دادهها به صورت cross-origin توسط سیاست same-origin مسدود نمیشود، علیرغم اینکه همچنان خطرناک است. در واقع، به همین دلیل است که حملات CSRF ممکن هستند و به همین دلیل است که باید اقدامات اضافی برای جلوگیری از آنها انجام دهیم — مانند استفاده از کوکیهای SameSite و توکنهای CSRF.
بهعنوان یک توسعهدهنده، زمانی که به احتمال زیاد با سیاست same-origin مواجه میشوید، هنگام ارسال درخواستهای cross-origin از کدهای JavaScript در حال اجرا در مرورگر است.
بهعنوان مثال، فرض کنید یک صفحه وب در https://foo.com دارید که شامل کدهای JavaScript فرانتاند است. اگر این JavaScript سعی کند یک درخواست HTTP به https://bar.com/data.json (یک origin متفاوت) ارسال کند، درخواست ارسال و توسط سرور bar.com پردازش میشود، اما مرورگر کاربر پاسخ را مسدود میکند بهطوری که کدهای JavaScript از https://foo.com نمیتوانند آن را ببینند.
بهطور کلی، سیاست same-origin یک مکانیزم محافظت امنیتی بسیار مفید است. اما در حالی که در حالت عمومی خوب است، در برخی شرایط ممکن است بخواهید این محدودیت را کاهش دهید.
بهعنوان مثال، اگر یک API در api.example.com و یک برنامه فرانتاند JavaScript قابل اعتماد در حال اجرا روی www.example.com دارید، احتمالاً میخواهید درخواستهای cross-origin از دامنه قابل اعتماد www.example.com به API خود را مجاز کنید.
یا شاید یک API عمومی کاملاً باز دارید و میخواهید درخواستهای cross-origin را از هر جایی مجاز کنید تا توسعهدهندگان دیگر به راحتی بتوانند آن را با وبسایتهای خود ادغام کنند.
خوشبختانه، بیشتر مرورگرهای وب مدرن به شما اجازه میدهند درخواستهای cross-origin خاص به API خود را با تنظیم هدرهای Access-Control در پاسخهای API خود مجاز یا غیرمجاز کنید. در فصلهای بعدی این کتاب دقیقاً توضیح خواهیم داد که چگونه این کار را انجام دهید و این هدرها چگونه کار میکنند.