محتوای آموزشی وبلاگ نتآرام
برنامه فرانتاند روی رایانه شما به API اکسپرس وصل میشود، اما پس از انتشار سایت، مرورگر پیام CORS نشان میدهد و پاسخ API به کد صفحه نمیرسد. معمولاً نشانی صفحه و نشانی API مبدأ یکسان ندارند و مرورگر برای خواندن پاسخ، هدرهای مشخصی از سرور انتظار دارد. مبدأ از طرح اتصال، نام میزبان و پورت ساخته میشود؛ بنابراین
http://localhost:3000 و https://app.example.com یا دو زیردامنه متفاوت، یک مبدأ یکسان نیستند.در این آموزش مبدأ واقعی و پاسخ API را پیدا میکنیم، درخواست مقدماتی را آزمایش میکنیم و یک فهرست مشخص از سایتهای مجاز میسازیم. CORS جایگزین ورود، بررسی مجوز یا محافظت از داده نیست: محدودیت اصلی آن درباره دسترسی کد مرورگر به پاسخ است و کلاینتهای غیرمرورگر همچنان میتوانند مستقیماً درخواست بفرستند.
۱. خطا و درخواست واقعی را ببینید
سایت را روی دامنه نهایی باز کنید و
F12 بزنید. در Console پیام کامل و در Network درخواست مربوط به API را پیدا کنید. نشانی صفحه، نشانی درخواست، روش آن مانند GET یا POST و زمان خطا را یادداشت کنید. اگر پیش از درخواست اصلی یک درخواست OPTIONS دیده میشود، آن را نیز باز کنید؛ مرورگر برای بعضی درخواستها ابتدا درباره اجازه ارسال روش و هدرها سؤال میکند. به این درخواست مقدماتی preflight میگویند.پیام CORS گاهی نتیجه خطای دیگری است: اگر API قطع باشد، گواهی SSL نامعتبر باشد یا پراکسی یک صفحه خطا بدون هدر مناسب برگرداند، مرورگر ممکن است فقط اجازه خواندن پاسخ را گزارش کند. بنابراین کد پاسخ OPTIONS و درخواست اصلی، مقصد انتقال و خطاهای شبکه را با هم ببینید. رمز، کوکی یا توکن درخواست را در تصویر و تیکت عمومی منتشر نکنید.
۲. مبدأ درست را مشخص کنید
فرض کنیم صفحه در
https://app.example.com و API در https://api.example.com است. در تنظیم CORS معمولاً مبدأ صفحه، یعنی https://app.example.com، وارد میشود؛ نه مسیر کامل صفحه یا آدرس API. نام دامنه نمونه را با دامنه واقعی جایگزین کنید. پورت غیراستاندارد، اگر وجود دارد، بخشی از مبدأ است. وجود یا نبود www و تفاوت HTTP و HTTPS هم مهم است.اگر دامنه صفحه بعد از انتقال عوض میشود، آدرس نهایی مرورگر را ملاک قرار دهید. برای دیدن سرآیندهای پاسخ ساده یک API عمومی آزمایشی:
کد / دستورcurl -i https://api.example.com/health -H 'Origin: https://app.example.com'
این مثال فقط در صورتی مناسب است که مسیر سلامت عمومی و بیخطر خودتان را جایگزین کنید. در پاسخ دنبال
Access-Control-Allow-Origin بگردید. مقدار آن باید با مبدأ مجاز درخواست سازگار باشد. نتیجه curl بهتنهایی رفتار امنیتی مرورگر را شبیهسازی نمیکند؛ پاسخ واقعی صفحه را هم آزمایش میکنیم.۳. درخواست مقدماتی را جداگانه امتحان کنید
اگر مرورگر پیش از POST درخواست OPTIONS میفرستد، با نشانی و هدرهای واقعی آزمایشی آن را شبیهسازی کنید:
کد / دستورcurl -i -X OPTIONS https://api.example.com/profile \
-H 'Origin: https://app.example.com' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type'
این نمونه برای ترمینال لینوکس یا macOS است؛ در PowerShell ویندوز قواعد ادامه خط متفاوتاند. مسیر و نام هدرها را مطابق درخواست واقعی تغییر دهید و از اطلاعات خصوصی استفاده نکنید. پاسخ موفق مقدماتی باید روش و هدرهای درخواستشده را طبق سیاست API مجاز کند. اگر OPTIONS با ۴۰۱ یا انتقال به صفحه ورود متوقف میشود، ترتیب میانافزارها یا تنظیم پراکسی را بررسی کنید؛ مرورگر هنوز به درخواست اصلی نرسیده است.
اگر هدر
Access-Control-Allow-Origin دوبار یا با دو مقدار مختلف میآید، ممکن است هم برنامه و هم پراکسی آن را اضافه کرده باشند. باید مالک تنظیم مشخص شود؛ اضافهکردن سومین هدر مشکل را حل نمیکند.۴. CORS را برای مبدأهای مشخص در Express تنظیم کنید
در نسخه آزمایشی پروژه، بررسی کنید بسته
کد / دستورcors جزو وابستگیهای لازم زمان اجراست. اگر پروژه آن را ندارد، با نسخه سازگار و تأییدشده توسط توسعهدهنده، آن را نصب و تغییر فایل قفل را بررسی کنید. نمونه نصب در نسخه توسعه یا آزمایشی:npm install --save-prod cors
npm ls cors
فرمان اول فایلهای وابستگی را تغییر میدهد؛ آن را بیبرنامه روی تنها نسخه سالم سایت زنده اجرا نکنید. سپس، پیش از مسیرهایی که باید درخواست را دریافت کنند، تنظیمی شبیه زیر در برنامه Express قرار دهید:
کد / دستورconst express = require("express");
const cors = require("cors");
const app = express();
const allowedOrigins = new Set(["https://app.example.com"]);
app.use(cors({
origin(origin, callback) {
callback(null, Boolean(origin && allowedOrigins.has(origin)));
},
credentials: true,
}));
دامنه نمونه را با مبدأ مورد اعتماد خود عوض کنید. در این نمونه، اگر
Origin در فهرست نباشد یا وجود نداشته باشد، هدر اجازه CORS برای آن مبدأ صادر نمیشود؛ این کار بهتنهایی جلوی پردازش درخواست کلاینت غیرمرورگر را نمیگیرد. برای API خصوصی همچنان احراز هویت و مجوز سمت سرور لازماند. شکل import در پروژههای ES modules متفاوت است.این میانافزار در صورت استفاده سراسری، به درخواستهای مقدماتی مربوط هم رسیدگی میکند؛ ترتیب آن نسبت به احراز هویت و مسیرهای پروژه را بررسی کنید. اگر پروژه CORS را جای دیگری تنظیم کرده، نمونه دوم را بدون بررسی اضافه نکنید. تغییر را تست و فایلهای وابستگی هماهنگ را با روش انتشار پروژه منتقل کنید، سپس همان برنامه را از پنل Restart کنید.
۵. اگر از کوکی یا نشست استفاده میکنید
برای درخواست مرورگر همراه کوکی، کلاینت باید ارسال credentials را متناسب با طراحی برنامه فعال کند و سرور نیز به همان مبدأ مشخص اجازه دهد. مقدار
* برای Access-Control-Allow-Origin در پاسخ دارای credentials مناسب نیست. سیاست کوکی، Secure و SameSite نیز بر ارسال اثر دارند؛ درخواست بین دو زیردامنه میتواند cross-origin باشد، اما از نظر مفهوم site الزاماً cross-site نیست. در بعضی حالتهای واقعاً بینسایتی، مرورگر کوکی شخص ثالث را حتی با تنظیمات صحیح محدود میکند.اگر هدر اجازه بر اساس Origin تغییر میکند، کش باید تفاوت Origin را در نظر بگیرد؛ هدر
Vary: Origin را در پاسخ بررسی کنید. CORS جایگزین حفاظت CSRF برای عملیات مبتنی بر کوکی نیست. اجازه دادن به هر دامنه صرفاً برای حذف خطای مرورگر ممکن است داده کاربر را در معرض دسترسی ناخواسته قرار دهد.۶. از مرورگر واقعی تأیید کنید
در Network دوباره پاسخ OPTIONS و سپس درخواست اصلی را ببینید. بعد یک Origin نامجاز را در محیط آزمایشی امتحان کنید تا مطمئن شوید هدر اجازه برای آن صادر نمیشود. موفقیت پاسخ
curl بدون بررسی مرورگر، کوکی و نتیجه واقعی API کافی نیست. اگر هنوز خطا دارید، نام دقیق Origin، پاسخ پراکسی و کد وضعیت را با خروجی برنامه مقایسه کنید.برای اجرای برنامههای سازگار صفحه هاست Node.js نتآرام را ببینید. جزئیات سیاست مرورگر در راهنمای CORS موزیلا و تنظیم میانافزار در مستندات Express آمده است.
برچسبها:
اشتراکگذاری:
لینکدینتلگرامایکس
مقاله قبلی
مقاله بعدی
دیدگاهها (۰)
دیدگاههای تاییدشده و پاسخهای تیم نتآرام
