๊ธฐ์กด์ PyJWT ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ฅผ Simple JWT ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋๋ก ์์ ํ์๋ค.
๋จธ๋ฆฟ์์์๋ ์ํ ํ๊ฒ ๊ทธ๋ ค์ง๋ ๊ทธ๋ฆผ์ด ์ง์ ์ฝ๋๋ก ์์ฑํ๋ ค๊ณ ํ๋ ๋งํ๋ ๋ถ๋ถ์ด ๋ง์๊ณ , ํ๋ฃจ์ข
์ผ ์๊ฐ์ ํ๋ฉฐ ๊ตฌํํ์๋ค.
๋งจ ์ฒ์์๋ JWT ์์ฑ๋ง์ ์๊ฐํ์ฌ PyJWT๋ฅผ ์ฌ์ฉํ์๋ค. ๊ทธ๋ฌ๋ PyJWT์ ๊ฒฝ์ฐ ์ ๋ง JWT ์์ฑ๋ง์ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ฌ์ django-rest-framework์์ JWT ์ธ์ฆ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ธฐ์กด์ ์ธ์ฆ ํด๋์ค๋ฅผ ์์๋ฐ์ ์๋ก์ด ํด๋์ค๋ฅผ ์์ฑํด์ค์ผํ๋ค. ์ฐพ์๋ณด๋ Simple JWT๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์๊ณ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฌธ์์ ์ฝ๋๋ฅผ ๋ณด๋ django-rest-framework์์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก JWT์ ์ธ์ฆ ๊ด๋ จ ์ฝ๋๋ฅผ ๋ชจ๋ ์์ฑํด์ค์ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์ฐ๊ธฐ๋ง ํ๋ฉด ๋์๋ค. ์ธ์ฆ์ ์ง์ ๊ตฌํํ๋ ๊ฒ๋ ์๋ฏธ์๊ฒ ์ง๋ง ํ ์์ ์์๋ ๋นจ๋ฆฌ ์ฝ๋๋ฅผ ์์ฑํ์ฌ์ผ ํ๊ธฐ ๋๋ฌธ์ SimpleJWT๋ฅผ ์ฌ์ฉํ๋ค.
ํ ์ผ ๋น๊ต
Simple JWT ์ฌ์ฉํ ๊ฒฝ์ฐ : User ๋ชจ๋ธ ํ์ฅ(django.contrib.auth.models์ User ์์๋ฐ์ ์ฌ์ฉ) + ๋ก๊ทธ์ธ ๋ก์ง ์ฒ๋ฆฌ
PyJWT ์ฌ์ฉํ ๊ฒฝ์ฐ : User ๋ชจ๋ธ ํ์ฅ(์์ ๋์ผ) + JWT ๊ด๋ จ(create, refresh ๋ฑ) + ๋ก๊ทธ์ธ ๋ก์ง ์ฒ๋ฆฌ + JWT ์ธ์ฆ ์ฒ๋ฆฌ
โก๏ธ ๋ฐ๋ผ์ Simple JWT๊ฐ ๋ ํจ์จ์ ์
ใฑ. (ํ๋ก ํธ โ ์๋ฒ) ํ๋ก ํธ์์ ์นด์นด์ค์๊ฒ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์์ฒญํ๊ธฐ ์ํ access_token ์ ๋ฌํด์ค
ใด. (์๋ฒ โ ์นด์นด์ค) ์ ๋ฌ๋ฐ์ access_token์ผ๋ก ์๋ฒ์์ ์นด์นด์ค์ ์ฌ์ฉ์ ์ ๋ณด POST ์์ฒญํจ
ใท. (์นด์นด์ค โ ์๋ฒ) ์นด์นด์ค๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ์ฌ์ฉ์ ์ ๋ณด๋ก ์ฐ๋ฆฌ DB์ ๋ฑ๋ก๋์ด ์๋ ์ ์ ์ธ์ง ์ฒดํฌ
ใท-1. ์ฐ๋ฆฌ DB์ ๋ฑ๋ก๋ ์ ์ ์ธ ๊ฒฝ์ฐ
ใท-2. ์ ๊ท ์ ์ ์ธ ๊ฒฝ์ฐ
โ ์ ๋ฌ๋ฐ์ ์นด์นด์ค ํ์๋ฒํธ๋ฅผ username์ผ๋ก, password๋ ์๋ฒ์์ ์์ฒด ์ค์ ํ์ฌ User(auth.models) ๊ฐ์ฒด ์์ฑ
ใน. (์๋ฒ โ ํ๋ก ํธ) Simple JWT์ ํ ํฐ ์์ฑ ๋ก์ง์ผ๋ก ์์ฑ๋ ํ ํฐ์ ํ๋ก ํธ์๊ฒ ์ ๋ฌ
ใน-1. ์ ๊ท ์ ์ ์ธ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ถ๊ฐ ์ ๋ณด ์
๋ ฅ๋ฐ์ AppUser(User ๋ชจ๋ธ ํ์ฅํ ๊ฒ) ๊ฐ์ฒด ์์ฑ
ใ
. ๋ก๊ทธ์ธ ์ต์ข
์๋ฃ!
์๋์ ์ด์๋ค์ simple-jwt ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด์ ๊ทธ๋๊ทธ๋ ์๊ธด ์ด์๋ค์ ์์๋๋ก ์์ฑํด๋์ ๊ฒ์ด์ด์ ๊ฐ๋ฐ์ ํ๋ฆ๊ณผ ๋์ผํจ
simple-jwt ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ token ์์ฑ ์ django.auth.models์์ ๊ธฐ๋ณธ ์ ๊ณตํ๋ User๋ฅผ ๋ฐํ์ผ๋ก ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ username, password์ ํด๋นํ๋ ์ ์ ๊ฐ ์๋์ง ํ์ธํด์ ํ ํฐ์ ์ ๊ณตํด์ค
# simple-jwt์ serializers.py
from django.contrib.auth import authenticate, get_user_model
class TokenObtainSerializer(serializers.Serializer):
username_field = get_user_model().USERNAME_FIELD
. . .
๋ฐ๋ผ์ User ๋ชจ๋ธ์ ์ฌ์ฉํด์ผํ๊ณ , ์ฐ๋ฆฌ ์๋น์ค์์๋ ์ถ๊ฐ๋ก ์ ์ฅํด์ผํ๋ ๊ฐ๋ค์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ User ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ์ปค์คํฐ๋ง์ด์ง์ ํด์ค์ผ ํ์
Django ๊ณต์๋ฌธ์ ๋ฅผ ๋ณด๋ ์ธ์ฆ ์ปค์คํฐ๋ง์ด์ง์ ๊ฒฝ์ฐ
A. ๊ธฐ์กด์ User ๋ชจ๋ธ ํ์ฅ (์ฑํ!)
B. ๊ธฐ์กด์ User ๋ชจ๋ธ ์ฌ์ฉํ์ง ์๊ณ ์์ ๋ค๋ฅธ ๋ชจ๋ธ๋ก ๋์ฒดํ๊ธฐ
2๊ฐ์ง ๋ฐฉ์์ด ์กด์ฌํ๋๋ฐ, simple-jwt ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ ๊ธฐ์กด์ User ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ํ ํฐ์ ์์ฑํ๊ธฐ ๋๋ฌธ์ A ๋ฐฉ์์ ์ฑํํจ
1. ์ํฉ
์ฐ๋ฆฌ ์๋น์ค๋ ์นด์นด์ค ๋ก๊ทธ์ธ๋ง ๊ฐ๋ฅํ๋๋ก ํ๊ธฐ ์ํด ์ฌ์ฉ์๊ฐ ์ง์ username, password๋ฅผ ์์ฑํ์ง ์์๋ ๋๋ ๊ตฌ์กฐ์์(์ฆ ์นด์นด์ค๋ก ๋ก๊ทธ์ธํ๊ธฐ ๋ฒํผ ํด๋ฆญํ๋ฉด ๋ฐ๋ก ๋ก๊ทธ์ธ ์ฒ๋ฆฌ๋๋ ๊ตฌ์กฐ)
๋ง์ฝ username, password๋ฅผ ์
๋ ฅํ๋ ๊ตฌ์กฐ์๋ค๋ฉด, ๋ฐ๋ก simple-jwt ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํด์ฃผ๋ POST api/token/ ๋ฅผ ํ๋ก ํธ์์ ์์ฒญํ๋ฉด ๋๋ ๊ฒ์ด์์
ํ์ง๋ง ๋ก๊ทธ์ธ ์์ฒญ ์ DB์ ์ฌ์ฉ์ ์ ์ฅ & ํ ํฐ ์์ฑ๊น์ง ํ๋ฒ์ ์ฒ๋ฆฌํด์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ํ ํฐ ์์ฑ ์์ฒญ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํด์ผํ ์ง ๊ณ ๋ฏผํจ
2. ํด๊ฒฐ๋ฐฉ์
์๊ฐ1) POST api/token/ ์๋ฒ์์ ์ง์ ์์ฒญ
์ํ ๋ฐฉ๋ฒ :
Requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ์ํ ๊ฐ๋ฅํจ
# ํ ํฐ ์์ฑ (simple-jwt)
def createJWT(self, user):
url = 'https://poppymail.shop/api/token/'
payload = {'username': user.username, 'password': '{์์์ ๊ฐ}'}
return requests.post(url, json=payload)
๊ฒฐ๋ก :
๋ก์ปฌ์์ ํ
์คํธํ ๋๋ ์ ์์ ์ผ๋ก ์ ์๋๋์์
ํ์ง๋ง ๋ฐฐํฌ ํ ํ
์คํธํ ๋๋ timeout์ด ๋จ
(๊ด๋ จ ๋ด์ฉ ํ์ธโก๏ธPoppyMail ๊ฐ๋ฐ์ผ์ง - ๋ฐฐํฌ ํ ํ
์คํธ)
์๊ฐ2) POST ์์ฒญํ์ง ์๊ณ , ํ ํฐ ์์ฑ ๋ก์ง์ผ๋ก ๋ฐ๋ก ์ฐ๊ฒฐ (์ฑํ!)
๊ด๋ จ ๋ด์ฉ ํ์ธโก๏ธPoppyMail ๊ฐ๋ฐ์ผ์ง - ๋ฐฐํฌ ํ ํ
์คํธ
simple-jwt์ ํ ํฐ ์์ฑ ๋ก์ง์ ๋ํ github ์ฝ๋๋ฅผ ๋ณด๋ ํด๋น ํจ์๋ฅผ ์ด์ฉํด ํ ํฐ์ ์์ฑํ๋ ๊ฒ์ด์์ผ๋ฏ๋ก, ํด๋น ํจ์๋ฅผ ์ฌ์ฉํ๋๋ก ํ์์(import ํ์ผ๋๊น ์ฌ์ฉ๊ฐ๋ฅํจ! - simple-jwt์ ๊ตฌํ๋์ด ์๋ ํจ์์ด๋๊น) / ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋๋ ๋์ ์๋ฆฌ๋ฅผ ์ดํดํ๋(ํจ์ ํธ์ถ ๋ฑ) ํ์ํ ๋ ๊ทธ ๋ถ๋ถ์ ์ง์ ํ์ฉํ ์ ์๋ ๊ฒ ๊ฐ์ ๋ฟ๋ฏํ๋ค. ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ฆฌ๋ฅผ ์ ์ด์ฉํ๋ ๊ฒ์ด ์ค์ํจ์ ๋๊ผ๋ค.
1. ์ํฉ ๋ฐ ๊นจ๋ฌ์
์๊ฐํด๋ณด๋ ๋จผ์ ํฐ ํ์ ์ก๊ณ ์ธ๋ถ์ฌํญ์ ์๊ฐํ์ด์ผ ํ๋๋ฐ ์ง๊ธ ๋์ ๊ฒฝ์ฐ์๋ ์ธ๋ถ์ฌํญ์ธ token ์์ฑ๋ถํฐ ์๊ฐํ๋ค๋ณด๋ ์ธ๋ถ โ ํฐ ํ์ ์๊ฐํ๋๋ฐ์ ์ฌ๋ฌ์์ด ์์๋ ๊ฒ ๊ฐ์. ์ฆ ํฐ ํ์ธ ๋ก๊ทธ์ธ/๋ก๊ทธ์์/ํํด ๊ตฌํ ๋ฐฉ์์ ์ก๊ณ ๊ทธ ์ธ๋ถ์ฌํญ์์ token ์ธ์ฆ ๋ฐฉ์์ ์ถ๊ฐํ๋ฉด ๋๋ ๊ฒ์ด์์
2. ํด๊ฒฐ ๋ฐฉ์
์๊ฐ1) dj-rest-auth ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํ๊ธฐ docs
์ฅ์ :
โ User ๋ฑ๋ก, ๋ก๊ทธ์ธ/๋ก๊ทธ์์, User model ๋ฐํ ๋ฐ ์
๋ฐ์ดํธ, ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ, e-mail๋ก ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ, ์์
๋ก๊ทธ์ธ ์ธ์ฆ ๋ฑ์ ๋ค์ํ ๊ธฐ๋ฅ ์ ๊ณต
๋จ์ :
โ ์ฐ๋ฆฌ ์๋น์ค์ ๋ก๊ทธ์ธ์ Id, PW ์
๋ ฅ ๋ฐฉ์์ด ์๋๋ฏ๋ก ๊ธฐ์กด์ ์์ฑ๋ ์ฝ๋๋ฅผ ์กฐ๊ธ ๋ณ๊ฒฝํด์ค์ผ ํจ
โ ์ฐ๋ฆฌ ์๋น์ค์์ ํ์ํ ๊ธฐ๋ฅ์ ๋นํด ๊ณผ๋ํ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ค
๋ฐ๋ผ์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฝ๋๋ ์์
๋ก๊ทธ์ธ(์ธ์ฆ์ฝ๋ ์ป๊ธฐ๋ถํฐ), ๊ธฐ์กด ๋ก๊ทธ์ธ์ ๋ํ ๋ก์ง์ด ์๋ฒฝํ๊ฒ ์ง์ฌ์์ผ๋ฏ๋ก ์ค๊ฐ์ ์ปค์คํฐ๋ง์ด์ง์ ํ๋ ๊ฒ์ด ๋ ๋ฒ๊ฑฐ๋กญ๋ค๋ ๊ฒฐ์ ์ ๋ด๋ฆผ
์๊ฐ2) ์ง์ ๋ก๊ทธ์ธ/๋ก๊ทธ์์/ํํด ๋ก์ง ๊ตฌํํ๊ธฐ (์ฑํ!)
๋ก๊ทธ์์์ ๊ฒฝ์ฐ์๋ ๊ทธ๋ฅ ํ ํฐ ์ฒ๋ฆฌ๋ง ํด์ฃผ๋ฉด ๋๊ณ , ํํด์ ๊ฒฝ์ฐ User ๋ชจ๋ธ๋ง ์ญ์ ํด์ฃผ๋ฉด ๋จ
class LoginView(APIView): # ๋ก๊ทธ์ธ
permission_classes = [AllowAny]
# ์นด์นด์คํก์ ์ฌ์ฉ์ ์ ๋ณด ์์ฒญ
def getUserFromKakao(self, request):
# DB์ ์๋์ง ํ๋ณ (auth_user)
def checkUserInDB(self, kakao_user):
# simple-JWT์ ์ฌ์ฉํด ํ ํฐ ์์ฑ ํด์ฃผ๋ ์ญํ ์ํ
def createJWT(self, user):
def post(self, request):
class AddUserInfoView(UpdateAPIView): # ์ฌ์ฉ์ ์ ๋ณด ์ถ๊ฐ ์
๋ ฅ(์
๋ฐ์ดํธ)
# ์ธ์ฆ & ํ๊ฐ - JWTAuthentication, IsAuthenticated (๊ธฐ๋ณธ ์ค์ )
class LogoutView(APIView): # ๋ก๊ทธ์์
# ์ธ์ฆ & ํ๊ฐ - JWTAuthentication, IsAuthenticated (๊ธฐ๋ณธ ์ค์ )
class SignoutView(DestroyAPIView): # ํํด
# auth_user ์ญ์ ํ๋ฉด -> AppUser, OutstandingToken, BlacklistedToken๋ ์ญ์ ๋จ (์๋ก cascade๋ก ์ค์ ๋์ด ์์)
# ์ธ์ฆ & ํ๊ฐ - JWTAuthentication, IsAuthenticated (๊ธฐ๋ณธ ์ค์ )
์์ ์ฝ๋ ๊ตฌ์กฐ๋ก views.py๋ฅผ ์์ฑํ์ฌ ์ฒ๋ฆฌํจ
1. ์ํฉ
์ฐ๋ฆฌ ์๋น์ค์์ ์ฌ์ฉ์ ์ต์ด ๋ก๊ทธ์ธ ์ ์ถ๊ฐ๋ก ํ์ ์ ๋ณด๋ฅผ ์
๋ ฅํด์ผ ํจ
์ด๋ ์น ํ์ด์ง์ด๋ค๋ณด๋ ์ฌ์ฉ์๊ฐ ์ถ๊ฐ ์
๋ ฅ ์๋ฃํ๊ณ ๋ค๋ก ๊ฐ๊ธฐ ๋๋ฌ์ ๋ค์ ํ์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์์
2. ํด๊ฒฐ๋ฐฉ์
์๊ฐ) PATCH๋ก ์ค์ ํ๊ธฐ (์ฑํ!)
์ฌ์ฉ์ ์ ๋ณด ์ถ๊ฐ ์ ์ฅ์ด๋ผ๋ ์๊ฐ์ ์ฌ๋ก์กํ ์ฒ์์๋ POST๋ก๋ง ์๊ฐํ์๋๋ฐ, ์๊ฐํด๋ณด๋ ๋ฏธ๋ฆฌ ํด๋น ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ์์ฑํด๋๊ณ UPDATE๋ก API ์ค์ ์ ํด๋๋ฉด ํด๊ฒฐ ๊ฐ๋ฅํ ๊ฒ์ด์์
์ฆ ๋ณ๊ฒฝํ๋ฉด ๋ณ๊ฒฝํ๋๋ก ์ ์ฅ๋๊ฒ ํ๋ ๊ฒ์ด๋ค! ์ด๋ PUT๊ณผ PATCH๊ฐ ์๋๋ฐ ์์น์ ์ ์ฒด ํญ๋ชฉ์ ๋ชจ๋ ์
๋ ฅํ๋ ๊ฒ์ด์ง๋ง ๋ถ๋ถ์ ์ธ ์
๋ฐ์ดํธ๋ก์ ์ฒ๋ฆฌํ๊ธฐ ์ํด PATCH๋ก ์ค์ ํจ
1. ์ํฉ
์ฐ๋ฆฌ ์๋น์ค์์๋ ๊ฐ์ธ๋ง๋ค ์ ํด์ง ์ฐ์ฒดํต ๋งํฌ์ ์ ์ํ๋ฉด ์๋ฌด๋ ํธ์ง๋ฅผ ์์ฑํ ์ ์๋๋ก ๊ตฌ์ฑํจ
์ด๋ ์ด๋ค ์
์์ ์ธ ์ฌ์ฉ์๊ฐ url์ ๋ณ๊ฒฝํ์ฌ ๋ค๋ฅธ ์ฌ๋์ ํธ์ง์ ๋ง๋ฌด๊ฐ๋ด๋ก ํธ์ง๋ฅผ ์์ฑํ ์ํฉ์ด ๋ฒ์ด์ง ์ ์์
์ค์ ๋ก ์ต๋ช
์ง๋ฌธ ์๋น์ค์ธ Ask์ ๊ฒฝ์ฐ ask.kr/{์ฌ์ฉ์ id} ํํ์ url์ ์ ์ํ๋ฉด ํด๋น ์ฌ์ฉ์์๊ฒ ์ง๋ฌธ์ ์์ฑํ ์ ์๋๋ฐ, ์ {์ฌ์ฉ์ id}๋ง ๋ฐ๊ฟ์ ์์ฒญํ๋ ํด๋น id ๊ฐ์ ์ฌ์ฉ์์ ๋ํ ์ง๋ฌธ ์์ฑ ํ์ด์ง๋ก ์ด๋์ด ๋์์
์ด๋ฅผ ๋ฐํ์ผ๋ก ์ฐ๋ฆฌ ์๋น์ค์ ์ฌ์ฉ์๊ฐ ์์น ์๋ ํธ์ง๋ฅผ ๋ฐ์ง ์๊ฒ ํ๊ธฐ ์ํด url ๊ตฌ์ฑ์ ๋ํด ๊ณ ๋ฏผํจ
2. ๊ณ ๋ฏผ ๋ฐฉ์
์๊ฐ1) ์ฐ์ฒดํต ํค ๊ฐ ํ๋์ unique=True ์ค์ ํ ๊ฒฝ์ฐ
URL ํํ : poppymail/{secret_key}
์ฅ์ : ๋น๋ฐ ํค ๊ฐ ๊ฒน์น ํ๋ฅ 0
๋จ์ : ๋น๋ฐ ํค ๊ฐ์ด 8์๋ฆฌ์ด๊ณ , char ํ์
์ด๋ฏ๋ก ๋งค๋ฒ ์์ฑํ ๋๋ง๋ค ํด๋น ๊ฐ์ด ์ด๋ฏธ ์กด์ฌํ๋์ง ์ฐ์ฒดํต ํ
์ด๋ธ์์ ํ์ธํด์ผ ํ๋ฏ๋ก db์ ๋ถ๋ด์ด ํด ๊ฒ์
์๊ฐ2) unique=True ์ค์ X (์ฑํ!)
URL ํํ : poppymail/<int:pk>/?key={key}
์ฅ์ : ์๊ฐ1์ ๋จ์ ์ด ๋ณด์๋จ
๋จ์ : URL์ ํํ์์์ฒ๋ผ ์ ๋ฌ๋ pk์ ํด๋นํ๋ ์ฐ์ฒดํต์ key๊ฐ๊ณผ ์ ๋ฌ๋ key๊ฐ์ด ์ผ์นํ๋์ง ์ฒ๋ฆฌํด์ค์ผ ํจ
๊ฒฐ๋ก ) ์๊ฐ1๋ณด๋ค๋ key ๊ฐ์ ๋น๊ตํ๋ ๋ก์ง์ผ๋ก ์ฒ๋ฆฌํ๋๊ฒ ๋ ํจ์จ์ ์ผ ๊ฒ ๊ฐ์์ ์๊ฐ2๋ฅผ ์ฑํํจ !