-
-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
π Add Korean translation for `docs/ko/docs/tutorial/security/simple-oβ¦
β¦auth2.md` (#5744)
- Loading branch information
1 parent
5a29797
commit d6997ab
Showing
1 changed file
with
315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
# ν¨μ€μλμ Bearerλ₯Ό μ΄μ©ν κ°λ¨ν OAuth2 | ||
|
||
μ΄μ μ΄μ μ₯μμ λΉλνκ³ λλ½λ λΆλΆμ μΆκ°νμ¬ μμ ν 보μ νλ¦μ κ°λλ‘ νκ² μ΅λλ€. | ||
|
||
## `username`μ `password` μ»κΈ° | ||
|
||
**FastAPI** 보μ μ νΈλ¦¬ν°λ₯Ό μ¬μ©νμ¬ `username` λ° `password`λ₯Ό κ°μ Έμ¬ κ²μ λλ€. | ||
|
||
OAuth2λ (μ°λ¦¬κ° μ¬μ©νκ³ μλ) "ν¨μ€μλ νλ‘μ°"μ μ¬μ©ν λ ν΄λΌμ΄μΈνΈ/μ μ κ° `username` λ° `password` νλλ₯Ό νΌ λ°μ΄ν°λ‘ 보λ΄μΌ ν¨μ μ§μ ν©λλ€. | ||
|
||
κ·Έλ¦¬κ³ μ¬μμλ νλμ μ΄λ¦μ κ·Έλ κ² μ§μ ν΄μΌ νλ€κ³ λμ μμ΅λλ€. λ°λΌμ `user-name` λλ `email`μ μλνμ§ μμ΅λλ€. | ||
|
||
νμ§λ§ κ±±μ νμ§ μμλ λ©λλ€. νλ°νΈμλμμ μ΅μ’ μ¬μ©μμκ² μνλ λλ‘ νμν μ μμ΅λλ€. | ||
|
||
κ·Έλ¦¬κ³ λ°μ΄ν°λ² μ΄μ€ λͺ¨λΈμ μνλ λ€λ₯Έ μ΄λ¦μ μ¬μ©ν μ μμ΅λλ€. | ||
|
||
κ·Έλ¬λ λ‘κ·ΈμΈ *κ²½λ‘ μλ*μ κ²½μ° μ¬μκ³Ό νΈνλλλ‘ μ΄λ¬ν μ΄λ¦μ μ¬μ©ν΄μΌ ν©λλ€(μλ₯Ό λ€μ΄ ν΅ν© API λ¬Έμ μμ€ν μ μ¬μ©ν μ μμ΄μΌ ν©λλ€). | ||
|
||
μ¬μμλ λν `username`κ³Ό `password`κ° νΌ λ°μ΄ν°λ‘ μ μ‘λμ΄μΌ νλ€κ³ λͺ μλμ΄ μμ΅λλ€(λ°λΌμ μ¬κΈ°μλ JSONμ΄ μμ΅λλ€). | ||
|
||
### `scope` | ||
|
||
μ¬μμλ ν΄λΌμ΄μΈνΈκ° λ€λ₯Έ νΌ νλ "`scope`"λ₯Ό λ³΄λΌ μ μλ€κ³ λμ μμ΅λλ€. | ||
|
||
νΌ νλ μ΄λ¦μ `scope`(λ¨μν)μ΄μ§λ§ μ€μ λ‘λ 곡백μΌλ‘ ꡬλΆλ "λ²μ"κ° μλ κΈ΄ λ¬Έμμ΄μ λλ€. | ||
|
||
κ° "λ²μ"λ κ³΅λ°±μ΄ μλ λ¬Έμμ΄μ λλ€. | ||
|
||
μΌλ°μ μΌλ‘ νΉμ 보μ κΆνμ μ μΈνλ λ° μ¬μ©λ©λλ€. λ€μμ λ΄ μλ€: | ||
|
||
* `users:read` λλ `users:write`λ μΌλ°μ μΈ μμμ λλ€. | ||
* `instagram_basic`μ νμ΄μ€λΆ/μΈμ€νκ·Έλ¨μμ μ¬μ©ν©λλ€. | ||
* `https://www.googleapis.com/auth/drive`λ Googleμμ μ¬μ©ν©λλ€. | ||
|
||
!!! μ 보 | ||
OAuth2μμ "λ²μ"λ νμν νΉμ κΆνμ μ μΈνλ λ¬Έμμ΄μ λλ€. | ||
|
||
`:`κ³Ό κ°μ λ€λ₯Έ λ¬Έμκ° μλμ§ λλ URLμΈμ§λ μ€μνμ§ μμ΅λλ€. | ||
|
||
μ΄λ¬ν μΈλΆ μ¬νμ ꡬνμ λ°λΌ λ€λ¦ λλ€. | ||
|
||
OAuth2μ κ²½μ° λ¬Έμμ΄μΌ λΏμ λλ€. | ||
|
||
## `username`κ³Ό `password`λ₯Ό κ°μ Έμ€λ μ½λ | ||
|
||
μ΄μ **FastAPI**μμ μ 곡νλ μ νΈλ¦¬ν°λ₯Ό μ¬μ©νμ¬ μ΄λ₯Ό μ²λ¦¬ν΄ λ³΄κ² μ΅λλ€. | ||
|
||
### `OAuth2PasswordRequestForm` | ||
|
||
λ¨Όμ `OAuth2PasswordRequestForm`μ κ°μ Έμ `/token`μ λν *κ²½λ‘ μλ*μμ `Depends`μ μμ‘΄μ±μΌλ‘ μ¬μ©ν©λλ€. | ||
|
||
=== "νμ΄μ¬ 3.7 μ΄μ" | ||
|
||
```Python hl_lines="4 76" | ||
{!> ../../../docs_src/security/tutorial003.py!} | ||
``` | ||
|
||
=== "νμ΄μ¬ 3.10 μ΄μ" | ||
|
||
```Python hl_lines="2 74" | ||
{!> ../../../docs_src/security/tutorial003_py310.py!} | ||
``` | ||
|
||
`OAuth2PasswordRequestForm`μ λ€μμ μ¬μ©νμ¬ νΌ λ³Έλ¬Έμ μ μΈνλ ν΄λμ€ μμ‘΄μ±μ λλ€: | ||
|
||
* `username`. | ||
* `password`. | ||
* `scope`λ μ νμ μΈ νλλ‘ κ³΅λ°±μΌλ‘ ꡬλΆλ λ¬Έμμ΄λ‘ ꡬμ±λ ν° λ¬Έμμ΄μ λλ€. | ||
* `grant_type`(μ νμ μΌλ‘ μ¬μ©). | ||
|
||
!!! ν | ||
OAuth2 μ¬μμ μ€μ λ‘ `password`λΌλ κ³ μ κ°μ΄ μλ `grant_type` νλλ₯Ό *μꡬ*νμ§λ§ `OAuth2PasswordRequestForm`μ μ΄λ₯Ό κ°μνμ§ μμ΅λλ€. | ||
|
||
μ¬μ©ν΄μΌ νλ€λ©΄ `OAuth2PasswordRequestForm` λμ `OAuth2PasswordRequestFormStrict`λ₯Ό μ¬μ©νλ©΄ λ©λλ€. | ||
|
||
* `client_id`(μ νμ μΌλ‘ μ¬μ©) (μμ μμλ νμνμ§ μμ΅λλ€). | ||
* `client_secret`(μ νμ μΌλ‘ μ¬μ©) (μμ μμλ νμνμ§ μμ΅λλ€). | ||
|
||
!!! μ 보 | ||
`OAuth2PasswordRequestForm`μ `OAuth2PasswordBearer`μ κ°μ΄ **FastAPI**μ λν νΉμ ν΄λμ€κ° μλλλ€. | ||
|
||
`OAuth2PasswordBearer`λ **FastAPI**κ° λ³΄μ 체κ³μμ μλλ‘ ν©λλ€. κ·Έλμ OpenAPIμ κ·Έλ κ² μΆκ°λ©λλ€. | ||
|
||
κ·Έλ¬λ `OAuth2PasswordRequestForm`μ μ§μ μμ±νκ±°λ `Form` 맀κ°λ³μλ₯Ό μ§μ μ μΈν μ μλ ν΄λμ€ μμ‘΄μ±μΌ λΏμ λλ€. | ||
|
||
κ·Έλ¬λ μΌλ°μ μΈ μ¬μ© μ¬λ‘μ΄λ―λ‘ λ μ½κ² νκΈ° μν΄ **FastAPI**μμ μ§μ μ 곡ν©λλ€. | ||
|
||
### νΌ λ°μ΄ν° μ¬μ©νκΈ° | ||
|
||
!!! ν | ||
μ’ μμ± ν΄λμ€ `OAuth2PasswordRequestForm`μ μΈμ€ν΄μ€μλ 곡백μΌλ‘ ꡬλΆλ κΈ΄ λ¬Έμμ΄μ΄ μλ `scope` μμ±μ΄ μκ³ λμ μ μ‘λ κ° λ²μμ λν μ€μ λ¬Έμμ΄ λͺ©λ‘μ΄ μλ `scopes` μμ±μ΄ μμ΅λλ€. | ||
|
||
μ΄ μμ μμλ `scopes`λ₯Ό μ¬μ©νμ§ μμ§λ§ νμν κ²½μ°, κΈ°λ₯μ΄ μμ΅λλ€. | ||
|
||
μ΄μ νΌ νλμ `username`μ μ¬μ©νμ¬ (κ°μ§) λ°μ΄ν°λ² μ΄μ€μμ μ μ λ°μ΄ν°λ₯Ό κ°μ Έμ΅λλ€. | ||
|
||
ν΄λΉ μ¬μ©μκ° μμΌλ©΄ "μλͺ»λ μ¬μ©μ μ΄λ¦ λλ ν¨μ€μλ"λΌλ μ€λ₯κ° λ°νλ©λλ€. | ||
|
||
μ€λ₯μ κ²½μ° `HTTPException` μμΈλ₯Ό μ¬μ©ν©λλ€: | ||
|
||
=== "νμ΄μ¬ 3.7 μ΄μ" | ||
|
||
```Python hl_lines="3 77-79" | ||
{!> ../../../docs_src/security/tutorial003.py!} | ||
``` | ||
|
||
=== "νμ΄μ¬ 3.10 μ΄μ" | ||
|
||
```Python hl_lines="1 75-77" | ||
{!> ../../../docs_src/security/tutorial003_py310.py!} | ||
``` | ||
|
||
### ν¨μ€μλ νμΈνκΈ° | ||
|
||
μ΄ μμ μμ λ°μ΄ν°λ² μ΄μ€μ μ¬μ©μ λ°μ΄ν° νμμ νμΈνμ§λ§ μνΈλ₯Ό νμΈνμ§ μμμ΅λλ€. | ||
|
||
λ¨Όμ λ°μ΄ν°λ₯Ό Pydantic `UserInDB` λͺ¨λΈμ λ£κ² μ΅λλ€. | ||
|
||
μΌλ° ν μ€νΈ μνΈλ₯Ό μ μ₯νλ©΄ μ λλ (κ°μ§) μνΈ ν΄μ± μμ€ν μ μ¬μ©ν©λλ€. | ||
|
||
λ ν¨μ€μλκ° μΌμΉνμ§ μμΌλ©΄ λμΌν μ€λ₯κ° λ°νλ©λλ€. | ||
|
||
#### ν¨μ€μλ ν΄μ± | ||
|
||
"ν΄μ±"μ μΌλΆ μ½ν μΈ (μ΄ κ²½μ° ν¨μ€μλ)λ₯Ό ν‘μ€μμ€νλ κ²μ²λΌ 보μ΄λ μΌλ ¨μ λ°μ΄νΈ(λ¬Έμμ΄)λ‘ λ³ννλ κ²μ μλ―Έν©λλ€. | ||
|
||
μ νν λμΌν μ½ν μΈ (μ νν λμΌν ν¨μ€μλ)λ₯Ό μ λ¬ν λλ§λ€ μ νν λμΌν ν‘μ€μμ€μ΄ λ°μν©λλ€. | ||
|
||
κ·Έλ¬λ ν‘μ€μμ€μμ μνΈλ‘ λ€μ λ³νν μλ μμ΅λλ€. | ||
|
||
##### ν¨μ€μλ ν΄μ±μ μ¬μ©ν΄μΌ νλ μ΄μ | ||
|
||
λ°μ΄ν°λ² μ΄μ€κ° μ μΆλ κ²½μ° ν΄μ»€λ μ¬μ©μμ μΌλ° ν μ€νΈ μνΈκ° μλλΌ ν΄μλ§ κ°κ² λ©λλ€. | ||
|
||
λ°λΌμ ν΄μ»€λ λ€λ₯Έ μμ€ν μμ λμΌν μνΈλ₯Ό μ¬μ©νλ €κ³ μλν μ μμ΅λλ€(λ§μ μ¬μ©μκ° λͺ¨λ κ³³μμ λμΌν μνΈλ₯Ό μ¬μ©νλ―λ‘ μ΄λ μνν μ μμ΅λλ€). | ||
|
||
=== "Pνμ΄μ¬ 3.7 μ΄μ" | ||
|
||
```Python hl_lines="80-83" | ||
{!> ../../../docs_src/security/tutorial003.py!} | ||
``` | ||
|
||
=== "νμ΄μ¬ 3.10 μ΄μ" | ||
|
||
```Python hl_lines="78-81" | ||
{!> ../../../docs_src/security/tutorial003_py310.py!} | ||
``` | ||
|
||
#### `**user_dict`μ λν΄ | ||
|
||
`UserInDB(**user_dict)`λ λ€μμ μλ―Ένλ€: | ||
|
||
*`user_dict`μ ν€μ κ°μ λ€μκ³Ό κ°μ ν€-κ° μΈμλ‘ μ§μ μ λ¬ν©λλ€:* | ||
|
||
```Python | ||
UserInDB( | ||
username = user_dict["username"], | ||
email = user_dict["email"], | ||
full_name = user_dict["full_name"], | ||
disabled = user_dict["disabled"], | ||
hashed_password = user_dict["hashed_password"], | ||
) | ||
``` | ||
|
||
!!! μ 보 | ||
`**user_dict`μ λν μμΈν μ€λͺ μ [**μΆκ° λͺ¨λΈ** λ¬Έμ](../extra-models.md#about-user_indict){.internal-link target=_blank}λ₯Ό λ€μ μ½μ΄λ΄ μλ€. | ||
|
||
## ν ν° λ°ννκΈ° | ||
|
||
`token` μλν¬μΈνΈμ μλ΅μ JSON κ°μ²΄μ¬μΌ ν©λλ€. | ||
|
||
`token_type`μ΄ μμ΄μΌ ν©λλ€. μ¬κΈ°μλ "Bearer" ν ν°μ μ¬μ©νλ―λ‘ ν ν° μ νμ "`bearer`"μ¬μΌ ν©λλ€. | ||
|
||
κ·Έλ¦¬κ³ μ‘μΈμ€ ν ν°μ ν¬ν¨νλ λ¬Έμμ΄κ³Ό ν¨κ» `access_token`μ΄ μμ΄μΌ ν©λλ€. | ||
|
||
μ΄ κ°λ¨ν μμ μμλ μμ ν μμ νμ§ μκ³ , λμΌν `username`μ ν ν°μΌλ‘ λ°νν©λλ€. | ||
|
||
!!! ν | ||
λ€μ μ₯μμλ ν¨μ€μλ ν΄μ± λ° <abbr title="JSON Web Tokens">JWT</abbr> ν ν°μ μ¬μ©νμ¬ μ€μ 보μ ꡬνμ λ³Ό μ μμ΅λλ€. | ||
|
||
νμ§λ§ μ§κΈμ νμν μΈλΆ μ 보μ μ§μ€νκ² μ΅λλ€. | ||
|
||
=== "νμ΄μ¬ 3.7 μ΄μ" | ||
|
||
```Python hl_lines="85" | ||
{!> ../../../docs_src/security/tutorial003.py!} | ||
``` | ||
|
||
=== "νμ΄μ¬ 3.10 μ΄μ" | ||
|
||
```Python hl_lines="83" | ||
{!> ../../../docs_src/security/tutorial003_py310.py!} | ||
``` | ||
|
||
!!! ν | ||
μ¬μμ λ°λΌ μ΄ μμ μ λμΌνκ² `access_token` λ° `token_type`μ΄ ν¬ν¨λ JSONμ λ°νν΄μΌ ν©λλ€. | ||
|
||
μ΄λ μ½λμμ μ§μ μνν΄μΌ νλ©° ν΄λΉ JSON ν€λ₯Ό μ¬μ©ν΄μΌ ν©λλ€. | ||
|
||
μ¬μμ μ€μνκΈ° μν΄ μ€μ€λ‘ μ¬λ°λ₯΄κ² μννκΈ° μν΄ κ±°μ μ μΌνκ² κΈ°μ΅ν΄μΌ νλ κ²μ λλ€. | ||
|
||
λλ¨Έμ§λ **FastAPI**κ° μ²λ¦¬ν©λλ€. | ||
|
||
## μμ‘΄μ± μ λ°μ΄νΈνκΈ° | ||
|
||
μ΄μ μμ‘΄μ±μ μ λ°μ΄νΈλ₯Ό ν κ²λλ€. | ||
|
||
μ΄ μ¬μ©μκ° νμ±νλμ΄ μλ *κ²½μ°μλ§* `current_user`λ₯Ό κ°μ Έμ¬ κ²λλ€. | ||
|
||
λ°λΌμ `get_current_user`λ₯Ό μμ‘΄μ±μΌλ‘ μ¬μ©νλ μΆκ° μ’ μμ± `get_current_active_user`λ₯Ό λ§λλλ€. | ||
|
||
μ΄λ¬ν μμ‘΄μ± λͺ¨λ, μ¬μ©μκ° μ‘΄μ¬νμ§ μκ±°λ λΉνμ±μΈ κ²½μ° HTTP μ€λ₯λ₯Ό λ°νν©λλ€. | ||
|
||
λ°λΌμ μλν¬μΈνΈμμλ μ¬μ©μκ° μ‘΄μ¬νκ³ μ¬λ°λ₯΄κ² μΈμ¦λμμΌλ©° νμ± μνμΈ κ²½μ°μλ§ μ¬μ©μλ₯Ό μ»μ΅λλ€: | ||
|
||
=== "νμ΄μ¬ 3.7 μ΄μ" | ||
|
||
```Python hl_lines="58-66 69-72 90" | ||
{!> ../../../docs_src/security/tutorial003.py!} | ||
``` | ||
|
||
=== "νμ΄μ¬ 3.10 μ΄μ" | ||
|
||
```Python hl_lines="55-64 67-70 88" | ||
{!> ../../../docs_src/security/tutorial003_py310.py!} | ||
``` | ||
|
||
!!! μ 보 | ||
μ¬κΈ°μ λ°ννλ κ°μ΄ `Bearer`μΈ μΆκ° ν€λ `WWW-Authenticate`λ μ¬μμ μΌλΆμ λλ€. | ||
|
||
λͺ¨λ HTTP(μ€λ₯) μν μ½λ 401 "UNAUTHORIZED"λ `WWW-Authenticate` ν€λλ λ°νν΄μΌ ν©λλ€. | ||
|
||
λ² μ΄λ¬ ν ν°μ κ²½μ°(μ§κΈμ κ²½μ°) ν΄λΉ ν€λμ κ°μ `Bearer`μ¬μΌ ν©λλ€. | ||
|
||
μ€μ λ‘ μΆκ° ν€λλ₯Ό 건λλΈ μ μμΌλ©° μ¬μ ν μλν©λλ€. | ||
|
||
κ·Έλ¬λ μ¬κΈ°μμλ μ¬μμ μ€μνλλ‘ μ 곡λ©λλ€. | ||
|
||
λν μ΄λ₯Ό μμνκ³ (νμ¬ λλ λ―Έλμ) μ¬μ©νλ λκ΅¬κ° μμ μ μμΌλ©°, νμ¬ λλ λ―Έλμ μμ νΉμ μμ μ μ μ λ€μκ² μ μ©ν κ²μ λλ€. | ||
|
||
κ·Έκ²μ΄ νμ€μ μ΄μ μ λλ€ ... | ||
|
||
## νμΈνκΈ° | ||
|
||
λνν λ¬Έμ μ΄κΈ°: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. | ||
|
||
### μΈμ¦νκΈ° | ||
|
||
"Authorize" λ²νΌμ λλ¬λ΄ μλ€. | ||
|
||
μ격 μ¦λͺ μ μ¬μ©ν©λλ€. | ||
|
||
μ μ λͺ : `johndoe` | ||
|
||
ν¨μ€μλ: `secret` | ||
|
||
<img src="/img/tutorial/security/image04.png"> | ||
|
||
μμ€ν μμ μΈμ¦νλ©΄ λ€μκ³Ό κ°μ΄ νμλ©λλ€: | ||
|
||
<img src="/img/tutorial/security/image05.png"> | ||
|
||
### μμ μ μ μ λ°μ΄ν° κ°μ Έμ€κΈ° | ||
|
||
μ΄μ `/users/me` κ²½λ‘μ `GET` μμ μ μ§νν©μλ€. | ||
|
||
λ€μκ³Ό κ°μ μ¬μ©μ λ°μ΄ν°λ₯Ό μ»μ μ μμ΅λλ€: | ||
|
||
```JSON | ||
{ | ||
"username": "johndoe", | ||
"email": "johndoe@example.com", | ||
"full_name": "John Doe", | ||
"disabled": false, | ||
"hashed_password": "fakehashedsecret" | ||
} | ||
``` | ||
|
||
<img src="/img/tutorial/security/image06.png"> | ||
|
||
μ κΈ μμ΄μ½μ ν΄λ¦νκ³ λ‘κ·Έμμν λ€μ λμΌν μμ μ λ€μ μλνλ©΄ λ€μκ³Ό κ°μ HTTP 401 μ€λ₯κ° λ°μν©λλ€. | ||
|
||
```JSON | ||
{ | ||
"detail": "Not authenticated" | ||
} | ||
``` | ||
|
||
### λΉνμ±λ μ μ | ||
|
||
μ΄μ λΉνμ±λ μ¬μ©μλ‘ μλνκ³ , μΈμ¦ν΄λ΄ μλ€: | ||
|
||
μ μ λͺ : `alice` | ||
|
||
ν¨μ€μλ: `secret2` | ||
|
||
κ·Έλ¦¬κ³ `/users/me` κ²½λ‘μ ν¨κ» `GET` μμ μ μ¬μ©ν΄ λ΄ μλ€. | ||
|
||
λ€μκ³Ό κ°μ "Inactive user" μ€λ₯κ° λ°μν©λλ€: | ||
|
||
```JSON | ||
{ | ||
"detail": "Inactive user" | ||
} | ||
``` | ||
|
||
## μμ½ | ||
|
||
μ΄μ APIμ λν `username` λ° `password`λ₯Ό κΈ°λ°μΌλ‘ μμ ν 보μ μμ€ν μ ꡬνν μ μλ λκ΅¬κ° μμ΅λλ€. | ||
|
||
μ΄λ¬ν λꡬλ₯Ό μ¬μ©νμ¬ λ³΄μ μμ€ν μ λͺ¨λ λ°μ΄ν°λ² μ΄μ€ λ° λͺ¨λ μ¬μ©μ λλ λ°μ΄ν° λͺ¨λΈκ³Ό νΈνλλλ‘ λ§λ€ μ μμ΅λλ€. | ||
|
||
μ μΌν μ€μ μ μμ§ μ€μ λ‘ "μμ "νμ§ μλ€λ κ²μ λλ€. | ||
|
||
λ€μ μ₯μμλ μμ ν ν¨μ€μλ ν΄μ± λΌμ΄λΈλ¬λ¦¬μ <abbr title="JSON Web Tokens">JWT</abbr> ν ν°μ μ¬μ©νλ λ°©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€. |