آشنایی با CORS و مفاهیم اصلی آن

CORS and its Main Concepts

03 اسفند 1399
آشنایی با CORS و مفاهیم اصلی آن

مشکل CORS چیست؟

اگر شما نیز از توسعه دهندگان وب باشید با مشکلات CORS آشنا شده اید. در صورتی که با این مفهوم آشنا نیستید حتما مطالعه این مقاله را به شما پیشنهاد می کنم. ما در این مقاله مباحث ابتدایی HTTP را توضیح نخواهیم داد بنابراین داشتن درک صحیح و ساده از عملیات های HTTP برای هضم این  مقاله لازم است.

زمانی که ما در حال توسعه front-end هستیم در اکثر اوقات داده ای را نمایش می دهیم که جای دیگری (روی سرور دیگری) قرار دارد. به همین منظور مرورگر باید ابتدا یک درخواست HTTP را به سرور مقصد ارسال کند تا تمام داده های مورد نیاز ما را دریافت کند. ما در اینجا نام فرضی www.mywebsite.com را برای وب سایت خود در نظر می گیریم. آدرس API این وب سایت را نیز api.website.com در نظر می گیریم. زمانی که درخواستی به این API ارسال می شود، داده های ما به صورت JSON برای کاربر (هر کسی که درخواست را ارسال کرده است) برگردانده خواهند شد. ما در حال حاضر روی سایت www.mywebsite.com هستیم اما اگر این بار درخواست خود را به دامنه دیگری مانند www.anotherdomain.com ارسال کنیم چه می شود؟ با اجرای این درخواست خطایی به شکل زیر دریافت می کنیم:

Access to fetched has been blocked by CORS policy

CORS مخفف Cross-origin resource sharing یا به اشتراک گذاری منابع از چند سورس مختلف است. برای درک بهتر CORS باید با Same-Origin Policy شروع کنیم.

Same-Origin Policy چیست؟

مرورگرها و دنیای وب به طوری طراحی شده اند که قانونی به نام same-origin policy را اجرا می کنند. این قانون می گوید مقصد درخواست های ما باید با منبعی که به آن هستیم یکی باشد. زمانی مقصد درخواست و منبع آن یکی نیست که:

  • به یک دامنه یا زیردامنه دیگر متصل شویم.
  • به یک پروتکل دیگر متصل شویم.
  • به یک پورت دیگر متصل شویم.

به طور مثال تا زمانی که به وب سایت mywebsite.com متصل باشیم هیچ اشکالی ندارد که به منابع آن دسترسی داشته باشیم (مثلا https://mywebsite.com/image1.png) اما نمی توانیم به منابع وب سایت دیگری مانند anotherdomain.com دسترسی داشته باشیم. این مسئله به سادگی در تصویر زیر مشخص است:

origin (منابع) های مختلف در CORS
origin (منابع) های مختلف در CORS

شاید از خودتان بپرسید چرا قانون same-origin وجود دارد؟ فرض کنید هکری لینک مخربی را برای شما ارسال کرده باشد. شما با کلیک روی این لینک به وب سایت هکر منتقل می شوید (مثلا www.evilwebsite.com) که در ظاهر وب سایت بدی نیست اما در پشت صحنه یک iframe از وب سایت بانکی شما (مثلا www.bank.com) باز می شود و هکر با استفاده از کوکی هایی که در مرورگر شما است، شما را وارد حسابتان می کند. طبیعتا این مسئله یک رخنه امنیتی بزرگ است و نباید مجاز باشد. قانون same-origin برای جلوگیری از چنین حملاتی ایجاد شده است و می گوید که دسترسی به resource ها باید از همان origin ای باشد که به آن متصل هستیم. با وجود این قانون وب سایت www.evilwebsite.com نمی تواند به www.bank.com دسترسی داشته باشد.

CORS در سمت کلاینت

منظور ما از سمت کلاینت همان front-end یا مرورگر است. زمانی که وارد دنیای مرورگرها و front-end می شویم باید بدانید که قانون same-origin policy فقط مربوط به اسکریپت ها می شود اما مرورگر ها آن را بسط دادند تا شامل درخواست های جاوا اسکریپتی نیز بشود بنابراین به صورت پیش فرض ما فقط می توانیم به منابعی دسترسی داشته باشیم که از same-origin (از سایتی که در آن هستیم) باشند:

رد شدن درخواست CORS
رد شدن درخواست CORS

مسئله اینجاست که ما در مواقع بسیاری نیاز به برقراری ارتباط با origin های دیگر (وب سایت های دیگر) داریم. آیا راهی وجود دارد که بر اساس آن بتوانیم به شکل امن از منابع سایت های دیگر نیز استفاده کنیم؟ بله CORS همان راه حل ما است. برایتان توضیح دادم که CORS مخفف Cross-origin resource sharing یا به اشتراک گذاری منابع از چند سورس مختلف است و از همین نام متوجه می شویم که کار آن چیست. User agent ها (مثلا یک مرورگر یا کتابخانه axios یا هر agent دیگری که از آن برای اتصال به یک سایت استفاده شده است) می توانند از مکانیسم خاصی به نام CORS استفاده کنند تا نوع خاصی از درخواست های cross-origin را ارسال کنند. این عملیات با استفاده از تنظیم header های خاصی در درخواست HTTP شما انجام می شود.

زمانی که می خواهیم یک درخواست Cross-origin (درخواستی به منبع دیگر) را ارسال کنیم، مرورگر شما یک header خاص به نام Origin را به درخواست HTTP اضافه می کند. مقدار این header برابر با منبعی است که درخواست از آن ارسال شده است. سرور این درخواست را دریافت کرده و header هایش را بررسی می کند تا بداند هر درخواست از کجا آمده است.

CORS در سمت سرور

اگر شما توسعه دهنده سرور هستید باید header های مجموعه Access-Control را به پاسخ های سرور خود اضافه کنید. مرورگرها بر اساس مقدار این دسته از header ها می توانند مشخص کنند که چه نوع درخواست های cross-origin ای مجاز هستند. در صورتی که Access-Control در header شما نباشد، تمام درخواست های cross-origin بلوکه خواهند شد. تعداد header های مربوط به Access-Control بسیار زیاد است اما مرورگر فقط یک header خاص را برای مجاز دانستن درخواست های cross-origin می خواهد و آن هم Access-Control-Allow-Origin می باشد. مقداری که به این header می دهید مشخص خواهد کرد که چه مقصد هایی می توانند به این منبع (سرور ما) درخواست ارسال کنند. به طور مثال اگر قرار است وب سایت https://mywebsite.com به سرور و وب سایت ما (مثلا https://api.mywebsite.com) دسترسی داشته باشد باید آن را به header ذکر شده پاس بدهیم:

هدر access control در درخواست های CORS
هدر access control در درخواست های CORS

حالا اگر درخواستی از سمت https://mywebsite.com ارسال شود می تواند به منابع موجود در https://api.mywebsite.com نیز دسترسی داشته باشد. از این به بعد مرورگر مقدار موجود در Access-Control-Allow-Origin را با مقصد درخواست شما مقایسه می کند و اگر این دو یکی نباشند اجازه ارسال درخواست را نخواهید داشت. شما می توانید این دو حالت را در دو تصویر زیر مشاهده کنید:

درخواست صحیح CORS
درخواست صحیح CORS
درخواست غلط CORS
درخواست غلط CORS

در تصویر دوم خطای معروف CORS را مشاهده می کنیم. قسمت دوم این درخواست دقیقا چیزی که ما توضیح دادیم را ذکر می کند:

The 'Access-Control-Allow-Origin' header has a value

 'https://www.mywebsite.com' that is not equal

to the supplied origin.

در نظر داشته باشید که Access-Control-Allow-Origin می تواند مقدار * را نیز بگیرد که در این صورت تمام درخواست های CORS از هر منبعی مجاز خواهند بود. انجام این کار پیشنهاد نمی شود چرا که خطرات امنیتی خاص خودش را دارد.


منبع: وب‌سایت dev.to

نویسنده شوید

دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سمانه
21 تیر 1400
عالی بود . ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

jawad
13 خرداد 1400
عالی بود

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.