]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Add Korean translation for `docs/ko/docs/tutorial/security/oauth2-jwt.md` (#13333)
authorLee Yesong <yesong50@gmail.com>
Mon, 10 Mar 2025 12:29:03 +0000 (21:29 +0900)
committerGitHub <noreply@github.com>
Mon, 10 Mar 2025 12:29:03 +0000 (13:29 +0100)
docs/ko/docs/tutorial/security/oauth2-jwt.md [new file with mode: 0644]

diff --git a/docs/ko/docs/tutorial/security/oauth2-jwt.md b/docs/ko/docs/tutorial/security/oauth2-jwt.md
new file mode 100644 (file)
index 0000000..d8bac83
--- /dev/null
@@ -0,0 +1,273 @@
+# νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹±μ„ μ΄μš©ν•œ OAuth2, JWT ν† ν°μ„ μ‚¬μš©ν•˜λŠ” Bearer μΈμ¦
+
+λͺ¨λ“  λ³΄μ•ˆ νλ¦„을 κ΅¬μ„±ν–ˆμœΌλ―€λ‘œ, μ΄μ œ <abbr title="JSON Web Tokens">JWT</abbr> ν† ν°κ³Ό νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹±μ„ μ‚¬μš©ν•΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ•ˆμ „ν•˜κ²Œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€.
+
+이 μ½”λ“œλŠ” μ‹€μ œλ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜μ—¬ DB에 μ €μž₯ν•˜λŠ” λ“±μ˜ μž‘업에 ν™œμš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+이전 μž₯에 μ΄μ–΄μ„œ μ‹œμž‘ν•΄ λ΄…μ‹œλ‹€.
+
+## JWT
+
+JWT λŠ” "JSON Web Tokens" μ„ μ˜λ―Έν•©λ‹ˆλ‹€.
+
+JSON κ°μ²΄λ₯Ό κ³΅λ°±μ΄ μ—†λŠ” κΈ΄ λ¬Έμžμ—΄λ‘œ μΈμ½”λ”©ν•˜λŠ” ν‘œμ€€μ΄λ©°, λ‹€μŒκ³Ό κ°™μ€ ν˜•νƒœμž…λ‹ˆλ‹€:
+
+```
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
+```
+
+JWTλŠ” μ•”ν˜Έν™”λ˜μ§€ μ•Šμ•„ λˆ„ꡬ든지 ν† ν°μ—μ„œ μ •보λ₯Ό λ³΅μ›ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+ν•˜μ§€λ§Œ JWTλŠ” μ„œλͺ…λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μžμ‹ μ΄ λ°œκΈ‰ν•œ ν† ν°μ„ λ°›μ•˜μ„ λ•Œ, μ‹€μ œλ‘œ μžμ‹ μ΄ λ°œκΈ‰ν•œκ²Œ λ§žλŠ”μ§€ κ²€μ¦ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+만료 κΈ°κ°„이 μΌμ£ΌμΌμΈ ν† ν°μ„ λ°œν–‰ν–ˆλ‹€κ³  κ°€μ •ν•΄ λ΄…μ‹œλ‹€. λ‹€μŒ λ‚  μ‚¬μš©μžκ°€ ν† ν°μ„ κ°€μ Έμ™”을 λ•Œ, κ·Έ μ‚¬μš©μžκ°€ μ‹œμŠ€ν…œμ— μ—¬μ „νžˆ λ‘œκ·ΈμΈλ˜μ–΄ μžˆλ‹€λŠ” κ²ƒμ„ μ•Œ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+일주일 λ’€μ—λŠ” ν† ν°μ΄ λ§Œλ£Œλ  κ²ƒμ΄κ³ , μ‚¬μš©μžλŠ” μΈκ°€λ˜μ§€ μ•Šμ•„ μƒˆ ν† ν°μ„ λ°›κΈ° μœ„ν•΄ λ‹€μ‹œ λ‘œκ·ΈμΈν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€. λ§Œμ•½ μ‚¬μš©μž(λ˜λŠ” μ œ3자)κ°€ ν† ν°μ„ μˆ˜μ •ν•˜κ±°λ‚˜ λ§Œλ£ŒμΌμ„ λ³€κ²½ν•˜λ©΄, μ„œλͺ…이 μΌμΉ˜ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ•Œμ•„μ±Œ μˆ˜ μžˆμ„ κ²ƒμž…λ‹ˆλ‹€.
+
+λ§Œμ•½ JWT ν† ν°μ„ λ‹€λ€„보고, μž‘동 λ°©μ‹λ„ μ•Œμ•„보고 μ‹Άλ‹€λ©΄ <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> μ„ ν™•μΈν•˜μ‹­μ‹œμ˜€.
+
+## `PyJWT` μ„€μΉ˜
+
+파이썬으둜 JWT ν† ν°μ„ μƒμ„±ν•˜κ³  κ²€μ¦ν•˜λ €λ©΄ `PyJWT` λ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.
+
+[κ°€μƒν™˜κ²½](../../virtual-environments.md){.internal-link target=_blank} μ„ λ§Œλ“€κ³  ν™œμ„±ν™”ν•œ λ‹€μŒ `pyjwt` λ₯Ό μ„€μΉ˜ν•˜μ‹­μ‹œμ˜€:
+
+<div class="termy">
+
+```console
+$ pip install pyjwt
+
+---> 100%
+```
+
+</div>
+
+/// info | μ°Έκ³ 
+
+RSAλ‚˜ ECDSA κ°™μ€ μ „μž μ„œλͺ… μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λ €λ©΄, `pyjwt[crypto]`λΌλŠ” μ•”ν˜Έν™” λΌμ΄λΈŒλŸ¬λ¦¬ μ˜μ‘΄μ„±μ„ μ„€μΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.
+
+더 μžμ„Έν•œ λ‚΄μš©μ€ <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT μ„€μΉ˜</a> μ—μ„œ ν™•인할 μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+///
+
+## νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹±
+
+"ν•΄μ‹±(Hashing)"은 μ–΄λ–€ λ‚΄μš©(μ—¬κΈ°μ„œλŠ” νŒ¨μŠ€μ›Œλ“œ)을 ν•΄μ„ν•  μˆ˜ μ—†λŠ” μΌλ ¨μ˜ λ°”μ΄νŠΈ μ§‘ν•©(λ‹¨μˆœ λ¬Έμžμ—΄)으둜 λ³€ν™˜ν•˜λŠ” κ²ƒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
+
+λ™μΌν•œ λ‚΄μš©(λ˜‘κ°™μ€ νŒ¨μŠ€μ›Œλ“œ)을 ν•΄μ‹±ν•˜λ©΄ λ™μΌν•œ λ¬Έμžμ—΄μ„ μ–»μŠ΅λ‹ˆλ‹€.
+
+ν•˜μ§€λ§Œ κ·Έ λ¬Έμžμ—΄μ„ λ‹€μ‹œ νŒ¨μŠ€μ›Œλ“œλ‘œ λ˜λŒλ¦΄ μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€.
+
+### νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜λŠ” μ΄μœ 
+
+λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό νƒˆμ·¨λ‹Ήν•˜λ”라도, μΉ¨μž…μžλŠ” μ‚¬μš©μžμ˜ ν‰λ¬Έ νŒ¨μŠ€μ›Œλ“œ λŒ€μ‹  ν•΄μ‹œ κ°’λ§Œ μ–»μ„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+λ”°λΌμ„œ μΉ¨μž…μžλŠ” ν›”μΉœ μ‚¬μš©μž νŒ¨μŠ€μ›Œλ“œλ₯Ό λ‹€λ₯Έ μ‹œμŠ€ν…œμ—μ„œ ν™œμš©ν•  μˆ˜ μ—†μŠ΅λ‹ˆλ‹€. (λŒ€λ‹€μˆ˜ μ‚¬μš©μžκ°€ μ—¬λŸ¬ μ‹œμŠ€ν…œμ—μ„œ λ™μΌν•œ νŒ¨μŠ€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— ν‰λ¬Έ νŒ¨μŠ€μ›Œλ“œκ°€ μœ μΆœλ˜λ©΄ μœ„ν—˜ν•©λ‹ˆλ‹€.)
+
+## `passlib` μ„€μΉ˜
+
+PassLibλŠ” νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹œλ₯Ό λ‹€λ£¨λŠ” ν›Œλ₯­ν•œ νŒŒμ΄μ¬ νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€.
+
+λ§Žμ€ μ•ˆμ „ν•œ ν•΄μ‹œ μ•Œκ³ λ¦¬μ¦˜κ³Ό λ„ꡬ듀을 μ§€μ›ν•©λ‹ˆλ‹€.
+
+μΆ”μ²œν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ€ "Bcrypt"μž…λ‹ˆλ‹€.
+
+[κ°€μƒν™˜κ²½](../../virtual-environments.md){.internal-link target=_blank} μ„ λ§Œλ“€κ³  ν™œμ„±ν™”ν•œ λ‹€μŒ PassLib와 Bcryptλ₯Ό μ„€μΉ˜ν•˜μ‹­μ‹œμ˜€:
+
+<div class="termy">
+
+```console
+$ pip install "passlib[bcrypt]"
+
+---> 100%
+```
+
+</div>
+
+/// tip | νŒ
+
+`passlib`λ₯Ό μ‚¬μš©ν•˜μ—¬, **Django**, **Flask** μ˜ λ³΄μ•ˆ ν”ŒλŸ¬κ·ΈμΈμ΄λ‚˜ λ‹€λ₯Έ λ„κ΅¬λ‘œ μƒμ„±ν•œ νŒ¨μŠ€μ›Œλ“œλ₯Ό μ½μ„ μˆ˜ μžˆλ„둝 μ„€μ •ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
+
+예λ₯Ό λ“€μžλ©΄, FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό Django μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ κ°™μ€ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ λ°μ΄ν„°λ₯Ό κ³΅μœ ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. λ˜λŠ” κ°™μ€ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ Django μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ μ§„μ μœΌλ‘œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
+
+그리고 μ‚¬μš©μžλŠ” FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό Django μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— λ™μ‹œμ— λ‘œκ·ΈμΈν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+///
+
+## νŒ¨μŠ€μ›Œλ“œμ˜ ν•΄μ‹œμ™€ κ²€μ¦
+
+ν•„μš”ν•œ λ„ꡬλ₯Ό `passlib`μ—μ„œ μž„ν¬νŠΈν•©λ‹ˆλ‹€.
+
+PassLib "μ»¨ν…μŠ€νŠΈ(context)"λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. μ΄κ²ƒμ€ νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜κ³  κ²€μ¦ν•˜λŠ”λ° μ‚¬μš©ν•©λ‹ˆλ‹€.
+
+/// tip | νŒ
+
+PassLib μ»¨ν…μŠ€νŠΈλŠ” λ‹€μ–‘ν•œ ν•΄μ‹± μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•  μˆ˜ μžˆλŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜λ©°, λ” μ΄μƒ μ‚¬μš©μ΄ κΆŒμž₯λ˜μ§€ μ•ŠλŠ” μ˜€λž˜λœ ν•΄μ‹± μ•Œκ³ λ¦¬μ¦˜μ„ κ²€μ¦ν•˜λŠ” κΈ°λŠ₯도 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
+
+예λ₯Ό λ“€μ–΄, λ‹€λ₯Έ μ‹œμŠ€ν…œ(Django κ°™μ€)μ—μ„œ μƒμ„±ν•œ νŒ¨μŠ€μ›Œλ“œλ₯Ό μ½κ³  κ²€μ¦ν•  μˆ˜ μžˆμœΌλ©°, μƒˆλ‘œμš΄ νŒ¨μŠ€μ›Œλ“œλ₯Ό Bcrypt κ°™μ€ λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ ν•΄μ‹±ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
+
+그리고 λ™μ‹œμ— κ·ΈλŸ° λͺ¨λ“  μ•Œκ³ λ¦¬μ¦˜κ³Ό ν˜Έν™˜μ„±μ„ μœ μ§€ν•©λ‹ˆλ‹€.
+
+///
+
+μ‚¬μš©μžλ‘œλΆ€ν„° λ°›μ€ νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜λŠ” μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
+
+그리고 λ°›μ€ νŒ¨μŠ€μ›Œλ“œκ°€ μ €μž₯된 ν•΄μ‹œμ™€ μΌμΉ˜ν•˜λŠ”μ§€ κ²€μ¦ν•˜λŠ” λ˜ λ‹€λ₯Έ μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ„ μƒμ„±ν•©λ‹ˆλ‹€.
+
+그리고 μ‚¬μš©μžλ₯Ό μΈμ¦ν•˜κ³  λ°˜ν™˜ν•˜λŠ” λ˜ λ‹€λ₯Έ ν•¨μˆ˜λ„ μƒμ„±ν•©λ‹ˆλ‹€.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
+
+/// note
+
+μƒˆλ‘œμš΄ (κ°€μ§œ) λ°μ΄ν„°λ² μ΄μŠ€ `fake_users_db`λ₯Ό ν™•μΈν•˜λ©΄, ν•΄μ‹œ μ²˜λ¦¬λœ νŒ¨μŠ€μ›Œλ“œκ°€ μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€ λ³Ό μˆ˜ μžˆμŠ΅λ‹ˆλ‹€: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
+
+///
+
+## JWT ν† ν° μ²˜λ¦¬
+
+μ„€μΉ˜λœ λͺ¨λ“ˆμ„ μž„ν¬νŠΈ ν•©λ‹ˆλ‹€.
+
+JWT ν† ν° μ„œλͺ…에 μ‚¬μš©λ  μž„μ˜μ˜ λΉ„λ°€ν‚€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
+
+μ•ˆμ „ν•œ μž„μ˜μ˜ λΉ„λ°€ν‚€λ₯Ό μƒμ„±ν•˜λ €λ©΄ λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€:
+
+<div class="termy">
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+</div>
+
+그리고 μƒμ„±ν•œ λΉ„λ°€ν‚€λ₯Ό λ³΅μ‚¬ν•΄ λ³€μˆ˜ `SECRET_KEY`에 λŒ€μž…ν•©λ‹ˆλ‹€. (이 μ˜ˆμ œμ˜ λ³€μˆ˜ κ°’을 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€.)
+
+JWT ν† ν°μ„ μ„œλͺ…ν•˜λŠ” λ° μ‚¬μš©λ  μ•Œκ³ λ¦¬μ¦˜μ„ μœ„ν•œ λ³€μˆ˜ `ALGORITHM` μ„ μƒμ„±ν•˜κ³  `"HS256"` μœΌλ‘œ μ„€μ •ν•©λ‹ˆλ‹€.
+
+토큰 λ§Œλ£Œ κΈ°κ°„을 μœ„ν•œ λ³€μˆ˜λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
+
+응닡을 μœ„ν•œ ν† ν° μ—”λ“œν¬μΈνŠΈμ— μ‚¬μš©λ  Pydantic λͺ¨λΈμ„ μ •μ˜ν•©λ‹ˆλ‹€.
+
+μƒˆ μ•‘μ„ΈμŠ€ ν† ν°μ„ μƒμ„±ν•˜κΈ° μœ„ν•œ μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+
+## μ˜μ‘΄μ„± μˆ˜μ •
+
+`get_current_user` ν•¨μˆ˜λ₯Ό μ΄μ „κ³Ό λ™μΌν•œ ν† ν°μ„ λ°›λ„둝 μˆ˜μ •ν•˜λ˜, μ΄λ²ˆμ—λŠ” JWT ν† ν°μ„ μ‚¬μš©ν•˜λ„둝 ν•©λ‹ˆλ‹€.
+
+받은 ν† ν°μ„ λ””μ½”λ”©ν•˜μ—¬ κ²€μ¦ν•œ ν›„ ν˜„μž¬ μ‚¬μš©μžλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
+
+토큰이 μœ νš¨ν•˜μ§€ μ•Šλ‹€λ©΄ HTTP μ˜€λ₯˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+
+## `/token` κ²½λ‘œ μž‘μ—… μˆ˜μ •
+
+ν† ν°μ˜ λ§Œλ£Œ μ‹œκ°μ„ μ„€μ •ν•˜κΈ° μœ„ν•΄ `timedelta` λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
+
+μ‹€μ œ JWT μ•‘μ„ΈμŠ€ ν† ν°μ„ μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+
+### JWT "주체(subject)" `sub`에 λŒ€ν•œ κΈ°μˆ  μ„ΈλΆ€ μ‚¬ν•­
+
+JWT λͺ…세에 λ”°λ₯΄λ©΄ ν† ν°μ˜ μ£Όμ²΄λ₯Ό ν¬ν•¨ν•˜λŠ” `sub`λΌλŠ” ν‚€κ°€ μžˆμŠ΅λ‹ˆλ‹€.
+
+μ‚¬μš© μ—¬λΆ€λŠ” μ„ νƒμ‚¬ν•­μ΄μ§€λ§Œ, μ‚¬μš©μžμ˜ μ‹λ³„ μ •보λ₯Ό μ €μž₯ν•  μˆ˜ μžˆμœΌλ―€λ‘œ μ—¬κΈ°μ„œλŠ” μ΄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
+
+JWTλŠ” μ‚¬μš©μžλ₯Ό μ‹λ³„ν•˜κ³  μ‚¬μš©μžκ°€ APIλ₯Ό μ§μ ‘ μ‚¬μš©ν•  μˆ˜ μžˆλ„둝 ν—ˆμš©ν•˜λŠ” κ²ƒ μ™Έμ—λ„ λ‹€λ₯Έ μš©λ„λ‘œ μ‚¬μš©λ  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
+
+예λ₯Ό λ“€μ–΄ "μžλ™μ°¨"λ‚˜ "λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Ό"을 μ‹λ³„ν•˜λŠ” λ° μ‚¬μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+그리고 "μžλ™μ°¨λ₯Ό μš΄μ „ν•˜λ‹€"λ‚˜ "λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Όμ„ μˆ˜μ •ν•˜λ‹€"처럼 ν•΄λ‹Ή μ—”터티에 λŒ€ν•œ κΆŒν•œμ„ μΆ”κ°€ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+κ·Έ ν›„ μ΄ JWT ν† ν°μ„ μ‚¬μš©μž(λ˜λŠ” λ΄‡)μ—κ²Œ μ œκ³΅ν•˜λ©΄, κ·Έλ“€μ€ κ³„정을 λ”°λ‘œ λ§Œλ“€ ν•„μš” μ—†μ΄ APIκ°€ μƒμ„±ν•œ JWT ν† ν°λ§ŒμœΌλ‘œ μž‘μ—…(μžλ™μ°¨ μš΄μ „ λ˜λŠ” λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Ό νŽΈμ§‘)을 μˆ˜ν–‰ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+μ΄λŸ¬ν•œ κ°œλ…μ„ ν™œμš©ν•˜λ©΄ JWTλŠ” ν›¨μ”¬ λ” λ³΅μž‘ν•œ μ‹œλ‚˜λ¦¬μ˜€μ—λ„ μ‚¬μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+이 κ²½μš° μ—¬λŸ¬ μ—”ν„°ν‹°κ°€ λ™μΌν•œ IDλ₯Ό κ°€μ§ˆ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. μ˜ˆλ₯Ό λ“€μ–΄ fooλΌλŠ” IDλ₯Ό κ°€μ§„ μ‚¬μš©μž, μžλ™μ°¨, λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Όμ΄ μžˆμ„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+κ·Έλž˜μ„œ ID μΆ©λŒμ„ λ°©μ§€ν•˜κΈ° μœ„ν•΄, μ‚¬μš©μžμ˜ JWT ν† ν°μ„ μƒμ„±ν•  λ•Œ μ ‘λ‘μ‚¬λ‘œ `sub` ν‚€λ₯Ό μΆ”κ°€ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. μ˜ˆλ₯Ό λ“€μ–΄ `username:` μ„ λΆ™μ΄λŠ” λ°©μ‹μž…λ‹ˆλ‹€. μ΄ μ˜ˆμ œμ—μ„œλŠ” `sub` κ°’이 `username:johndoe`이 λ  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+κ°€μž₯ μ€‘μš”ν•œ μ μ€ `sub` ν‚€λŠ” μ „체 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ κ³ μœ ν•œ μ‹λ³„μžκ°€ λ˜μ–΄μ•Ό ν•˜λ©° λ¬Έμžμ—΄μ΄μ–΄μ•Ό ν•œλ‹€λŠ” μ μž…λ‹ˆλ‹€.
+
+## ν™•μΈν•΄λ΄…μ‹œλ‹€
+
+μ„œλ²„λ₯Ό μ‹€ν–‰ν•˜κ³  λ¬Έμ„œλ‘œ μ΄λ™ν•˜μ‹­μ‹œμ˜€: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+
+λ‹€μŒκ³Ό κ°™μ€ μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ³Ό μˆ˜ μžˆμŠ΅λ‹ˆλ‹€:
+
+<img src="/img/tutorial/security/image07.png">
+
+이전과 κ°™μ€ λ°©λ²•μœΌλ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μΈμ¦ν•˜μ‹­μ‹œμ˜€.
+
+λ‹€μŒ μΈμ¦ μ •보λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€:
+
+Username: `johndoe`
+Password: `secret`
+
+/// check
+
+μ½”λ“œ μ–΄λ””에도 ν‰λ¬Έ νŒ¨μŠ€μ›Œλ“œ "`secret`" μ΄ μ—†λ‹€λŠ” μ μ— μœ μ˜ν•˜μ‹­μ‹œμ˜€. ν•΄μ‹œλœ λ²„μ „λ§Œ μžˆμŠ΅λ‹ˆλ‹€.
+
+///
+
+<img src="/img/tutorial/security/image08.png">
+
+`/users/me/` λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ‹€μŒκ³Ό κ°™μ€ μ‘닡을 μ–»μ„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€:
+
+```JSON
+{
+  "username": "johndoe",
+  "email": "johndoe@example.com",
+  "full_name": "John Doe",
+  "disabled": false
+}
+```
+
+<img src="/img/tutorial/security/image09.png">
+
+개발자 λ„ꡬλ₯Ό μ—΄μ–΄λ³΄λ©΄ μ „솑된 λ°μ΄ν„°μ— ν† ν°λ§Œ ν¬ν•¨λœ κ²ƒμ„ ν™•인할 μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. νŒ¨μŠ€μ›Œλ“œλŠ” μ‚¬μš©μžλ₯Ό μΈμ¦ν•˜κ³  μ•‘μ„ΈμŠ€ ν† ν°μ„ λ°›κΈ° μœ„ν•œ μ²« λ²ˆμ§Έ μš”μ²­μ—λ§Œ μ „솑되며, μ΄ν›„μ—λŠ” μ „μ†‘λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€:
+
+<img src="/img/tutorial/security/image10.png">
+
+/// note
+
+`Bearer `둜 μ‹œμž‘ν•˜λŠ” `Authorization` ν—€λ”에 μ£Όλͺ©ν•˜μ‹­μ‹œμ˜€.
+
+///
+
+## `scopes` μ˜ κ³ κΈ‰ μ‚¬μš©λ²•
+
+OAuth2λŠ” "μŠ€μ½”ν”„(scopes)" λΌλŠ” κ°œλ…μ„ κ°–κ³  μžˆμŠ΅λ‹ˆλ‹€.
+
+이λ₯Ό μ‚¬μš©ν•˜μ—¬ JWT ν† ν°μ— νŠΉμ • κΆŒν•œ μ§‘합을 μΆ”κ°€ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+κ·Έ ν›„ μ΄ ν† ν°μ„ μ‚¬μš©μžμ—κ²Œ μ§μ ‘ μ œκ³΅ν•˜κ±°λ‚˜ μ œ3μžμ—κ²Œ μ œκ³΅ν•˜μ—¬, νŠΉμ • μ œν•œμ‚¬ν•­ ν•˜μ—μžˆλŠ” API와 ν†΅μ‹ ν•˜λ„둝 ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+**FastAPI** μ—μ„œμ˜ μ‚¬μš© λ°©λ²•κ³Ό ν†΅ν•© λ°©μ‹μ€ **심화 μ‚¬μš©μž μ•ˆλ‚΄μ„œ** μ—μ„œ μžμ„Ένžˆ λ°°μšΈ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+## μš”μ•½
+
+μ§€κΈˆκΉŒμ§€ μ‚΄νŽ΄λ³Έ λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ, OAuth2와 JWT κ°™μ€ ν‘œμ€€μ„ μ‚¬μš©ν•˜μ—¬ μ•ˆμ „ν•œ **FastAPI** μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+거의 λͺ¨λ“  ν”„λ ˆμž„μ›Œν¬μ—μ„œ λ³΄μ•ˆ μ²˜λ¦¬λŠ” μƒλ‹Ήνžˆ λ³΅μž‘ν•œ μ£Όμ œμž…λ‹ˆλ‹€.
+
+이λ₯Ό λ‹¨μˆœν™”ν•˜λŠ” λ§Žμ€ νŒ¨ν‚€μ§€λŠ” λ°μ΄ν„° λͺ¨λΈ, λ°μ΄ν„°λ² μ΄μŠ€, μ‚¬μš© κ°€λŠ₯ν•œ κΈ°λŠ₯듀에 λŒ€ν•΄ μ—¬λŸ¬ μ œμ•½μ΄ μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ¦¬κ³  μ§€λ‚˜μΉ˜κ²Œ λ‹¨μˆœν™”ν•˜λŠ” μΌλΆ€ νŒ¨ν‚€μ§€λ“€μ€ μ‹¬κ°ν•œ λ³΄μ•ˆ κ²°ν•¨μ„ κ°€μ§ˆ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
+
+---
+
+**FastAPI** λŠ” μ–΄λ–€ λ°μ΄ν„°λ² μ΄μŠ€, λ°μ΄ν„° λͺ¨λΈ, λ„ꡬ도 κ°•μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
+
+ν”„λ‘œμ νŠΈμ— κ°€μž₯ μ ν•©ν•œ κ²ƒμ„ μ„ νƒν•  μˆ˜ μžˆλŠ” μœ μ—°μ„±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
+
+그리고 `passlib` μ™€ `PyJWT` μ²˜λŸΌ μž˜ κ΄€λ¦¬λ˜κ³  λ„λ¦¬ μ‚¬μš©λ˜λŠ” νŒ¨ν‚€μ§€λ“€μ„ λ°”λ‘œ μ‚¬μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. **FastAPI** λŠ” μ™ΈλΆ€ νŒ¨ν‚€μ§€ ν†΅ν•©μ„ μœ„ν•΄ λ³΅μž‘ν•œ λ©”μ»€λ‹ˆμ¦˜μ΄ ν•„μš”ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
+
+κ·ΈλŸ¬λ‚˜ μœ μ—°μ„±, κ²¬κ³ μ„±, λ³΄μ•ˆμ„±μ„ ν•΄μΉ˜μ§€ μ•ŠμœΌλ©΄μ„œ κ³Όμ •을 λ‹¨μˆœν™”ν•  μˆ˜ μžˆλŠ” λ„ꡬ듀을 μ œκ³΅ν•©λ‹ˆλ‹€.
+
+그리고 OAuth2와 κ°™μ€ ν‘œμ€€ ν”„λ‘œν† μ½œμ„ λΉ„ꡐ적 κ°„λ‹¨ν•œ λ°©λ²•μœΌλ‘œ κ΅¬ν˜„ν•˜κ³  μ‚¬μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+더 μ„ΈλΆ„ν™”λœ κΆŒν•œ μ²΄κ³„λ₯Ό μœ„ν•΄ OAuth2의 "μŠ€μ½”ν”„"λ₯Ό μ‚¬μš©ν•˜λŠ” λ°©λ²•은 **심화 μ‚¬μš©μž μ•ˆλ‚΄μ„œ**μ—μ„œ λ” μžμ„Ένžˆ λ°°μšΈ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. OAuth2의 μŠ€μ½”ν”„λŠ” μ œ3자 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‚¬μš©μžλ₯Ό λŒ€μ‹ ν•΄ κ·Έλ“€μ˜ API와 μƒν˜Έμž‘μš©ν•˜λ„λ‘ κΆŒν•œμ„ λΆ€μ—¬ν•˜κΈ° μœ„ν•΄, Facebook, Google, GitHub, Microsoft, Twitter λ“±μ˜ λ§Žμ€ λŒ€ν˜• μΈμ¦ μ œκ³΅μ—…체듀이 μ‚¬μš©ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μž…λ‹ˆλ‹€.