committed by
GitHub
1 changed files with 153 additions and 0 deletions
@ -0,0 +1,153 @@ |
|||
### CORS (اشتراک منابع Cross-Origin) |
|||
|
|||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS یا "Cross-Origin"</a> به شرایطی اشاره دارد که در آن، یک فرانتاند که در مرورگر اجرا میشود، شامل کد **JavaScript** است که با یک بکاند ارتباط برقرار میکند، درحالیکه بکاند در یک "مبدأ" متفاوت از فرانتاند قرار دارد. |
|||
|
|||
--- |
|||
|
|||
## مبدأ (Origin) |
|||
|
|||
یک **مبدأ** ترکیبی از **پروتکل** (`http`, `https`)، **دامنه** (`myapp.com`, `localhost`, `localhost.tiangolo.com`) و **پورت** (`80`, `443`, `8080`) است. |
|||
|
|||
بنابراین، نمونههای زیر مبدأهای متفاوتی محسوب میشوند: |
|||
|
|||
- `http://localhost` |
|||
- `https://localhost` |
|||
- `http://localhost:8080` |
|||
|
|||
حتی اگر همگی در `localhost` باشند، به دلیل تفاوت در **پروتکل** یا **پورت**، مبدأهای متفاوتی در نظر گرفته میشوند. |
|||
|
|||
--- |
|||
|
|||
## مراحل |
|||
|
|||
فرض کنیم که یک فرانتاند در **مرورگر** شما در `http://localhost:8080` اجرا میشود و کد **JavaScript** آن در تلاش است که با یک بکاند در `http://localhost` ارتباط برقرار کند (چون پورتی مشخص نشده، مرورگر بهصورت پیشفرض **پورت ۸۰** را در نظر میگیرد). |
|||
|
|||
در این حالت، مرورگر ابتدا یک درخواست **OPTIONS** به **پورت ۸۰** ارسال میکند. اگر بکاند، هدرهای مناسب را برای مجاز کردن ارتباط از مبدأ متفاوت (`http://localhost:8080`) ارسال کند، مرورگر اجازه خواهد داد که جاوااسکریپت در فرانتاند، درخواست اصلی را به بکاند ارسال کند. |
|||
|
|||
برای این کار، بکاند باید یک لیست از **مبدأهای مجاز** داشته باشد. |
|||
|
|||
در این مورد، این لیست باید شامل `http://localhost:8080` باشد تا فرانتاند (`:8080`) بتواند به درستی کار کند. |
|||
|
|||
--- |
|||
|
|||
## کاراکترهای عام (Wildcards) |
|||
|
|||
همچنین میتوان لیست **مبدأهای مجاز** را `"*"` (بهعنوان **کاراکتر عام**) تنظیم کرد تا همهی مبدأها مجاز باشند. |
|||
|
|||
اما این روش فقط برای برخی از انواع ارتباطات قابل استفاده است و مواردی که شامل **احراز هویت** هستند را شامل نمیشود، مانند: |
|||
|
|||
- کوکیها |
|||
- هدرهای احراز هویت (مانند **Bearer Tokens**) |
|||
|
|||
پس، برای عملکرد صحیح، بهتر است **مبدأهای مجاز را بهصورت صریح مشخص کنید**. |
|||
|
|||
--- |
|||
|
|||
## استفاده از `CORSMiddleware` در **FastAPI** |
|||
|
|||
برای پیکربندی **CORS** در **FastAPI**، میتوان از `CORSMiddleware` استفاده کرد: |
|||
|
|||
1. **وارد کردن** `CORSMiddleware` |
|||
2. **ایجاد یک لیست از مبدأهای مجاز** (بهعنوان رشتههای متنی) |
|||
3. **اضافه کردن آن به عنوان Middleware به برنامهی FastAPI** |
|||
|
|||
همچنین میتوان مشخص کرد که بکاند اجازهی موارد زیر را دارد یا نه: |
|||
|
|||
- **احراز هویت** (مانند کوکیها، هدرهای Authorization و ...) |
|||
- **متدهای HTTP خاص** (`POST`, `PUT`) یا تمام متدها با `"*"` |
|||
- **هدرهای HTTP خاص** یا همهی آنها با `"*"` |
|||
|
|||
```python |
|||
from fastapi import FastAPI |
|||
from fastapi.middleware.cors import CORSMiddleware |
|||
|
|||
app = FastAPI() |
|||
|
|||
origins = [ |
|||
"http://localhost:8080", |
|||
"https://example.com", |
|||
] |
|||
|
|||
app.add_middleware( |
|||
CORSMiddleware, |
|||
allow_origins=origins, |
|||
allow_credentials=True, |
|||
allow_methods=["*"], |
|||
allow_headers=["*"], |
|||
) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## پارامترهای `CORSMiddleware` |
|||
|
|||
مقدارهای پیشفرض `CORSMiddleware` **بهشدت محدودکننده** هستند. بنابراین، باید بهطور **صریح** مشخص کنید که چه **مبدأهایی، متدها یا هدرهایی** مجاز هستند تا مرورگر اجازهی استفاده از آنها را در یک ارتباط **Cross-Origin** بدهد. |
|||
|
|||
پارامترهای پشتیبانیشده: |
|||
|
|||
- `allow_origins` - لیستی از مبدأهای مجاز برای درخواستهای **CORS**. مثلا: |
|||
|
|||
```python |
|||
['https://example.org', 'https://www.example.org'] |
|||
``` |
|||
|
|||
میتوانید از `['*']` برای اجازه دادن به تمام مبدأها استفاده کنید. |
|||
|
|||
- `allow_origin_regex` - یک **عبارت باقاعده (Regex)** برای تطبیق با مبدأهای مجاز. مثلا: |
|||
|
|||
```python |
|||
'https://.*\.example\.org' |
|||
``` |
|||
|
|||
- `allow_methods` - لیستی از **متدهای HTTP** که برای درخواستهای CORS مجاز هستند. مقدار پیشفرض `['GET']` است. میتوان از `['*']` برای مجاز کردن تمام متدها استفاده کرد. |
|||
|
|||
- `allow_headers` - لیستی از **هدرهای HTTP** که برای درخواستهای CORS پشتیبانی میشوند. مقدار پیشفرض `[]` است. میتوان از `['*']` برای اجازه دادن به تمام هدرها استفاده کرد. |
|||
|
|||
**هدرهای همیشه مجاز برای درخواستهای سادهی CORS**: |
|||
|
|||
- `Accept` |
|||
- `Accept-Language` |
|||
- `Content-Language` |
|||
- `Content-Type` |
|||
|
|||
- `allow_credentials` - تعیین میکند که آیا کوکیها در درخواستهای **Cross-Origin** پشتیبانی شوند یا نه. مقدار پیشفرض `False` است. |
|||
|
|||
- اگر مقدار `allow_origins` برابر `['*']` باشد، نمیتوان مقدار `allow_credentials` را `True` قرار داد. باید مبدأها را **صریحاً** مشخص کنید. |
|||
|
|||
- `expose_headers` - تعیین میکند که کدام هدرهای **پاسخ** باید برای مرورگر قابلدسترسی باشند. مقدار پیشفرض `[]` است. |
|||
|
|||
- `max_age` - مشخص میکند که مرورگر پاسخهای CORS را تا چند **ثانیه** کش کند. مقدار پیشفرض `600` ثانیه است. |
|||
|
|||
--- |
|||
|
|||
## انواع درخواستهای CORS |
|||
|
|||
### **۱. درخواستهای پیشپرواز (Preflight Requests)** |
|||
|
|||
درخواستهای `OPTIONS` که شامل هدرهای `Origin` و `Access-Control-Request-Method` هستند. |
|||
|
|||
در این حالت، **Middleware** درخواست را بررسی کرده و با هدرهای مناسب CORS، پاسخ `200` (موفق) یا `400` (نامعتبر) ارسال میکند. |
|||
|
|||
### **۲. درخواستهای ساده (Simple Requests)** |
|||
|
|||
هر درخواستی که شامل **هدر `Origin`** باشد. در این حالت، **Middleware** درخواست را بهصورت عادی پردازش میکند اما هدرهای مناسب CORS را در پاسخ اضافه میکند. |
|||
|
|||
--- |
|||
|
|||
## اطلاعات بیشتر |
|||
|
|||
برای اطلاعات بیشتر دربارهی **CORS**، میتوانید مستندات **Mozilla** را بررسی کنید: |
|||
|
|||
🔗 [Mozilla CORS Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) |
|||
|
|||
--- |
|||
|
|||
## نکته فنی |
|||
|
|||
همچنین میتوان از `CORSMiddleware` موجود در **Starlette** بهصورت مستقیم استفاده کرد: |
|||
|
|||
```python |
|||
from starlette.middleware.cors import CORSMiddleware |
|||
``` |
|||
|
|||
**FastAPI** برخی **Middlewareها** را در `fastapi.middleware` برای راحتی توسعهدهندگان ارائه میدهد. اما بیشتر Middlewareهای موجود مستقیماً از **Starlette** گرفته شدهاند. |
Loading…
Reference in new issue