mirror of https://github.com/tiangolo/fastapi.git
Add Persian translation for docs/fa/docs/tutorial/security/first-steps.md
This commit is contained in:
parent
bee1c226a3
commit
3795665e73
|
|
@ -0,0 +1,231 @@
|
|||
# امنیت - گامهای اولیه
|
||||
|
||||
فرض کنید شما یک API backend را در یک دامنه دارید.
|
||||
|
||||
و یک frontend را در یک دامنه دیگر یا در مسیر متفاوتی از همان دامنه (یا در یک برنامه موبایل) دارید.
|
||||
|
||||
و شما میخواهید یک راه برای frontend داشته باشید تا با استفاده از یک نام کاربری و رمز عبور با backend احراز هویت کند.
|
||||
|
||||
میتوانیم از OAuth2 برای ساخت این ویژگی با FastAPI استفاده کنیم.
|
||||
|
||||
اما بیایید از ابزارهای ارائه شده توسط FastAPI برای مدیریت امنیت استفاده کنیم و زمان خواندن مشخصات طولانی OAuth2 را برای پیدا کردن آن قسمتهای کوچکی که نیاز دارید، صرفه جویی کنیم.
|
||||
|
||||
## چگونگی کارکرد
|
||||
|
||||
ابتدا فقط از این کد استفاده کنیم تا ببینیم چگونه کار میکند، سپس برای درک اینکه چه اتفاقی میافتد برگردیم.
|
||||
|
||||
## ایجاد `main.py`
|
||||
|
||||
کد مثال را در فایل `main.py` کپی کنید:
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! tip
|
||||
Prefer to use the `Annotated` version if possible.
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
## اجرا کنید
|
||||
|
||||
!!! اطلاعات
|
||||
ابتدا <a href="https://andrew-d.github.io/python-multipart/" class="external-link" target="_blank">`python-multipart`</a> را نصب کنید.
|
||||
|
||||
به عنوان مثال، با استفاده از دستور `pip install python-multipart`.
|
||||
|
||||
این به خاطر این است که **OAuth2** برای ارسال `username` و `password` از "form data" استفاده میکند.
|
||||
|
||||
برای اجرای مثال، از دستور زیر استفاده کنید:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## بررسی کنید
|
||||
|
||||
به مستندات تعاملی در آدرس <a href="[http://127.0.0.1:8000/docs ↗](http://127.0.0.1:8000/docs)" class="external-link" target="_blank">[http://127.0.0.1:8000/docs ↗](http://127.0.0.1:8000/docs)</a> بروید.
|
||||
|
||||
چیزی شبیه به این را خواهید دید:
|
||||
|
||||
<img src="/img/tutorial/security/image01.png">
|
||||
|
||||
!!! بررسی "Authorize button!"
|
||||
شما قبلا یک "Authorize" جدید برای خود دریافت کردهاید.
|
||||
|
||||
و *path operation* شما یک قفل کوچک در گوشه بالا و راست دارد که میتوانید بر روی آن کلیک کنید.
|
||||
|
||||
و اگر بر روی آن کلیک کنید، فرم احراز هویت کوچکی برای تایپ کردن `username` و `password` (و سایر فیلدهای اختیاری) دارید:
|
||||
|
||||
<img src="/img/tutorial/security/image02.png">
|
||||
|
||||
!!! نکته
|
||||
مهم نیست که چه چیزی را در فرم تایپ کنید، هنوز کار نخواهد کرد. اما به زودی به آنجا خواهیم رسید.
|
||||
|
||||
به طور طبیعی، این فرانتاند برای کاربران نهایی نیست، اما این یک ابزار خودکار عالی برای مستند کردن تعاملی تمام API شما است.
|
||||
|
||||
تیم فرانتاند میتواند از آن استفاده کند (که میتوانید خودتان باشید).
|
||||
|
||||
میتواند توسط برنامهها و سیستمهای شخص ثالث نیز استفاده شود.
|
||||
|
||||
و همچنین میتوانید خودتان از آن برای دیباگ کردن، بررسی و تست این برنامه استفاده کنید.
|
||||
|
||||
## جریان (flow) `password`
|
||||
|
||||
حالا بیایید به عقب برگردیم و بفهمیم همه اینها چی هستند.
|
||||
|
||||
جریان (flow) "password" یکی از راههای ("flows") تعریف شده در OAuth2 برای مدیریت امنیت و احراز هویت است.
|
||||
|
||||
پروتکل استاندارد OAuth2 به گونهای طراحی شده است که بکاند یا API مستقل از سروری باشد که کاربر را تأیید کند.
|
||||
|
||||
اما در این مورد، همان برنامه **FastAPI** باید API و احراز هویت را اداره کند.
|
||||
|
||||
بنابراین، بیایید آن را از آن دیدگاه ساده شده مورد بررسی قرار دهیم:
|
||||
|
||||
* کاربر `username` و `password` را در فرانتاند تایپ میکند و `Enter` را میزند.
|
||||
* فرانتاند (در مرورگر کاربر) این `username` و `password` را به یک URL خاص در API ما ارسال میکند (با استفاده از `tokenUrl="token"` که تعریف شده است).
|
||||
* در API `username` و `password` را بررسی کرده و با یک "token" پاسخ میدهد (هنوز هیچ کدام از اینها را پیادهسازی نکردهایم).
|
||||
* یک "token" فقط یک رشته با برخی محتوا است که بعداً میتوانیم از آن برای تأیید این کاربر استفاده کنیم.
|
||||
* به طور معمول، یک توکن باید بعد از مدتی منقضی شود.
|
||||
* بنابراین، کاربر در یک زمان بعدی باید دوباره وارد شود.
|
||||
* و اگر توکن به سرقت رفت، خطر کمتری وجود خواهد داشت. این مثل یک کلید دائمی نیست که برای همیشه کار خواهد کرد (در بیشتر موارد).
|
||||
* فرانتاند این توکن را موقتاً در جایی ذخیره میکند.
|
||||
* کاربر در فرانتاند برای رفتن به بخش دیگری از برنامه وب فرانتاند کلیک میکند.
|
||||
* فرانتاند نیاز به دریافت بیشتری از دادهها از API دارد.
|
||||
* اما برای آن endpoint خاص، نیاز به احراز هویت دارد.
|
||||
* بنابراین، برای احراز هویت با API ما، یک هدر `Authorization` با مقدار `Bearer` به علاوه توکن ارسال میکند.
|
||||
* اگر توکن شامل `foobar` باشد، محتوای هدر `Authorization` به شکل زیر خواهد بود: `Bearer foobar`.
|
||||
|
||||
## کلاس `OAuth2PasswordBearer` در **FastAPI**
|
||||
|
||||
فریم ورک **FastAPI** ابزارهای مختلفی را در سطوح مختلف انتزاع (abstraction) ، برای پیادهسازی ویژگیهای امنیتی، فراهم میکند.
|
||||
|
||||
در این مثال، ما از **OAuth2** با جریان(flow) **Password** و با استفاده از یک توکن **Bearer** استفاده خواهیم کرد. برای این کار از کلاس `OAuth2PasswordBearer` استفاده میکنیم.
|
||||
|
||||
!!! اطلاعات
|
||||
یک توکن "bearer" تنها گزینهای نیست.
|
||||
|
||||
اما بهترین مورد برای استفاده ما است.
|
||||
|
||||
و ممکن است برای اکثر موارد ، بهترین گزینه باشد، مگر اینکه یک کارشناس OAuth2 باشید و دقیقاً بدانید چرا گزینه دیگری وجود دارد که به نیازهای شما میخورد.
|
||||
|
||||
در آن صورت، **FastAPI** نیز ابزارهای لازم را برای ساخت آن ارائه میدهد.
|
||||
|
||||
زمانی که ما یک نمونه از کلاس `OAuth2PasswordBearer` ایجاد میکنیم، ما پارامتر `tokenUrl` را به عنوان ورودی میدهیم. این پارامتر حاوی URL است که مشتری (فرانتاند در حال اجرا در مرورگر کاربر) برای ارسال `username` و `password` به منظور دریافت یک توکن، استفاده خواهد کرد.
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! tip
|
||||
Prefer to use the `Annotated` version if possible.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! نکته
|
||||
در اینجا `tokenUrl="token"` به یک URL نسبی به نام `token` اشاره دارد که هنوز آن را ایجاد نکردهایم. زیرا که این یک URL نسبی است، معادل با `./token` است.
|
||||
|
||||
با توجه به استفاده از URL نسبی، اگر API شما در آدرس `https://example.com/` قرار داشت، در این صورت به `https://example.com/token` ارجاع میدهد. اما اگر API شما در آدرس `https://example.com/api/v1/` قرار داشت، در این صورت به `https://example.com/api/v1/token` ارجاع میدهد.
|
||||
|
||||
استفاده از URL نسبی، برای اطمینان از اینکه برنامه شما حتی در مورد کاربرد پیشرفته مانند [پشت پراکسی](../../advanced/behind-a-proxy.md){.internal-link target=_blank}، کار میکند، بسیار مهم است.
|
||||
|
||||
این پارامتر یک عملیات مسیر / *path operation* را ایجاد نمیکند، بلکه اعلام میکند که URL `/token` آن است که مشتری باید برای دریافت توکن استفاده کند. این اطلاعات در OpenAPI و سپس در سیستمهای مستندات تعاملی API (interactive API documentation systems) استفاده میشود.
|
||||
|
||||
ما به زودی همچنین path operation واقعی را نیز ایجاد خواهیم کرد.
|
||||
|
||||
!!! اطلاعات
|
||||
اگر شما یک "پایتونیست" بسیار سختگیر هستید، ممکن است از سبک نام پارامتر `tokenUrl` به جای `token_url` ناراضی باشید.
|
||||
|
||||
این به دلیل استفاده از همان نام در مشخصات OpenAPI است. بنابراین اگر نیاز به بررسی بیشتر در مورد هر یک از این روشهای امنیتی داشته باشید، میتوانید آن را کپی و پیست کنید تا اطلاعات بیشتری در مورد آن پیدا کنید.
|
||||
|
||||
متغیر `oauth2_scheme` یک نمونه از `OAuth2PasswordBearer` است، اما همچنین یک "قابل فراخوانی" (*callable*) است.
|
||||
|
||||
میتوان آن را به شکل زیر فراخوانی کرد:
|
||||
|
||||
```Python
|
||||
oauth2_scheme(some, parameters)
|
||||
```
|
||||
|
||||
بنابراین، میتوانید آن را با استفاده از `Depends` در یک وابستگی به اشتراک بگذارید.
|
||||
|
||||
### استفاده از آن
|
||||
|
||||
اکنون میتوانید `oauth2_scheme` را در یک وابستگی با `Depends` ارسال کنید.
|
||||
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! tip
|
||||
Prefer to use the `Annotated` version if possible.
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
این وابستگی یک `str` ارائه میدهد که به پارامتر `token` تابع *path operation* اختصاص داده میشود.
|
||||
|
||||
فریم ورک **FastAPI** خواهد دانست که میتواند از این وابستگی برای تعریف یک "security scheme" در طرح OpenAPI (و مستندات API خودکار) استفاده کند.
|
||||
|
||||
!!! اطلاعات "جزئیات فنی"
|
||||
فریم ورک **FastAPI** میداند که میتواند از کلاس `OAuth2PasswordBearer` (در یک وابستگی اعلام شده) برای تعریف security scheme در OpenAPI استفاده کند، زیرا که این کلاس از `fastapi.security.oauth2.OAuth2` به ارث میبرد که به نوبه خود از`fastapi.security.base.SecurityBase` به ارث میبرد.
|
||||
|
||||
تمامی ابزارهای امنیتی که با OpenAPI (و مستندات API خودکار) یکپارچه شدهاند، از `SecurityBase` به ارث میروند، به همین دلیل **FastAPI** میتواند بداند که چگونه آنها را در OpenAPI بهکار ببرد.
|
||||
|
||||
## عملکرد آن چیست؟
|
||||
درخواست (request) بررسی میکند و به دنبال هدر `Authorization` میگردد، سپس بررسی میکند که آیا مقدار آن شامل `Bearer` و یک توکن است و در نهایت توکن را به عنوان `str` باز میگرداند.
|
||||
|
||||
اگر هدر `Authorization` را پیدا نکرد، یا مقدار آن شامل یک توکن `Bearer` نباشد، مستقیماً با یک خطای کد وضعیت 401 (`UNAUTHORIZED`) پاسخ خواهد داد.
|
||||
|
||||
شما حتی نیازی به بررسی وجود توکن برای بازگرداندن خطا ندارید. شما میتوانید مطمئن باشید که اگر تابع شما اجرا شود، یک `str` در آن توکن وجود دارد.
|
||||
|
||||
شما میتوانید این را در مستندات تعاملی امتحان کنید.
|
||||
|
||||
<img src="/img/tutorial/security/image03.png">
|
||||
|
||||
هنوز اعتبار توکن را تأیید نکردهایم، اما این یک شروع خوب است.
|
||||
|
||||
## خلاصه
|
||||
|
||||
بنابراین، با اضافه کردن تنها ۳ یا ۴ خط کد اضافی، شما به یک شکل اولیه از امنیت دسترسی رسیدهاید.
|
||||
Loading…
Reference in New Issue