Skip to content

Latest commit

ย 

History

History
222 lines (152 loc) ยท 6.55 KB

File metadata and controls

222 lines (152 loc) ยท 6.55 KB

4์ฃผ์ฐจ - 5. token์ธ์ฆ

Token Authentication

BasicAuthentication : ๋ณด์•ˆ์ด ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.
SessionAuthentication : ์™ธ๋ถ€ ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ ํ•˜๋‹ค.

๋”ฐ๋ผ์„œ TokenAuthentication์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋ฉฐ Mobile Client์— ์ ํ•ฉํ•˜๋‹ค.

์ˆ˜ํ–‰๊ณผ์ •

  1. username, password์™€ 1:1 ๋งค์นญ๋˜๋Š” ๊ณ ์œ  key ์ƒ์„ฑ, ๋ฐœ๊ธ‰
  2. ๋ฐœ๊ธ‰๋ฐ›์€ Token์„ API์š”์ฒญ์— ๋‹ด์•„ ์ธ์ฆ์ฒ˜๋ฆฌ

Token Authentication ์„ค์ •ํ•˜๊ธฐ

๊ธฐ์กด์˜ ์ธ์ฆ ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ•˜๋‚˜์˜ ๋‹จ๊ณ„๋ฅผ ๋” ๊ฑฐ์ณ์•ผํ•œ๋‹ค.
settings.py์˜ INSTALLED_APPS์— ์•„๋ž˜์™€ ๊ฐ™์ด
rest_framework.authtoken์„ ์ถ”๊ฐ€ํ•˜๊ณ  migrate ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',
    ...
]

migrate ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์•„ ๋ชจ๋ธ๊ณผ ์—ฐ๊ด€์ด ์žˆ๋‹ค.

Token ๋ชจ๋ธ ํด๋ž˜์Šค

rest_framework๋‚ด๋ถ€์˜ authtoken์•ฑ์˜ models.py์— ์žˆ๋Š” Tokenํด๋ž˜์Šค๋‹ค.
OneToOneField๋ฅผ ์ด์šฉํ•ด ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž์— ํ•˜๋‚˜์˜ Token์„ ๋ฐœ๊ธ‰ํ•œ๋‹ค.

class Token(models.Model):
    """
    The default authorization token model.
    """
    key = models.CharField(_("Key"), max_length=40, primary_key=True)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, related_name='auth_token',
        on_delete=models.CASCADE, verbose_name=_("User")
    )
    created = models.DateTimeField(_("Created"), auto_now_add=True)

Token ์ƒ์„ฑํ•˜๊ธฐ

User Instance๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Token์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

Token์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. authtoken์•ฑ์˜ views.py์˜ ObtainAuthToken์„ ์ด์šฉํ•ด ์ƒ์„ฑ

ObtainAuthToken์˜ ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. Python ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•œ ์ƒ์„ฑ

ํ† ํฐ ์ƒ์„ฑํ•˜๊ธฐ

python manage.py drf_create_token <username>

ํ† ํฐ ๊ฐ•์ œ๋กœ ์žฌ์ƒ์„ฑํ•˜๊ธฐ

python manage.py drf_create_token -r <username>
  1. signal์„ ์ด์šฉํ•œ ์‚ฌ์šฉ์ž ์ƒ์„ฑ์‹œ Token์ƒ์„ฑ

signal์€ ํŠน์ • ๋™์ž‘์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ฒ˜๋ฆฌ๋  ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
์•„๋ž˜์—์„œ ์‚ฌ์šฉํ•œ post_save๋Š” DB์— ์ •๋ณด๊ฐ€ ์ €์žฅ๋œ ์งํ›„์— ํŠน์ • ๋™์ž‘์ด ์ˆ˜ํ–‰๋œ๋‹ค.

from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

์ƒˆ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๋งˆ๋‹ค settings.AUTH_USER_MODEL๋กœ signal์„ ๋ณด๋‚ธ๋‹ค. user์™€ 1:1 ๋งค์นญ๋˜๋Š” ํ† ํฐ์„ ์ƒ์„ฑํ•ด AUTH_USER_MODEL๋กœ ๋ณด๋‚ด์ค€๋‹ค.

์ƒ์„ฑํ•œ Token์„ ํš๋“ํ•˜๋Š” ๋ฐฉ๋ฒ•

Token์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋Š” URL Path๋ฅผ ์ง€์ •ํ•˜๊ณ  ๊ทธ URL์— POST์š”์ฒญ์„ ๋ณด๋‚ด Token์„ ํš๋“ํ•œ๋‹ค.
obtain_auth_token์€ Token์„ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•œ ObtainAuthToken์— as_view๋ฅผ ๋ถ™์ธ๊ฒƒ์ด๋‹ค.
์•„๋ž˜์™€ ๊ฐ™์ด urls.py์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  ๊ทธ URL์— POST์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

...
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    path('api-auth/', include(rest_framework.urls)),
    path('api-token-auth/', obtain_auth_token),
]

๋ฐœ๊ธ‰๋ฐ›์€ Token์„ API์š”์ฒญ์— ๋‹ด์•„ ์ธ์ฆ์ฒ˜๋ฆฌ

  • ์ธ์ฆ ์„ฑ๊ณต์‹œ
request.user = <Django User Instance>
request.auth = <rest_framework.authtoken.models.BasicToken Instance>

TokenAuthentication ๊ตฌํ˜„ํ•˜๊ธฐ

Authentication, Permission ๊ฐ•์˜์— ์‚ฌ์šฉํ•œ ํ”„๋กœ์ ํŠธ์™€ ๋™์ผ

1. settings.py ์ˆ˜์ •ํ•˜๊ธฐ

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',
    'userpost.apps.UserpostConfig',
]

2. migrate ์‹คํ–‰ํ•˜๊ธฐ

python manage.py makemigrations
python manage.py migrate

์•„๋ž˜์™€ ๊ฐ™์ด authtoken ๋ชจ๋ธ๋„ ์ ์šฉ๋˜์—ˆ๋‹ค.


3. views.py ์ˆ˜์ •ํ•˜๊ธฐ

settings.py์—์„œ ์ „์—ญ์œผ๋กœ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์กด์žฌํ•œ๋‹ค.

...
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly


class UserPostViewSet(viewsets.ModelViewSet):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]
    ...

4. ๋ช…๋ น์–ด๋กœ Token ์ƒ์„ฑํ•˜๊ธฐ

python manage.py drf_create_token <username>

์•„๋ž˜์™€ ๊ฐ™์ด Token์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


ํ† ํฐ์ด ์กด์žฌํ•˜๋Š” ์ƒํƒœ์—์„œ ์žฌ์ƒ์„ฑํ•˜๋ฉด ๋™์ผํ•œ ํ† ํฐ์ด ๋ฐœ๊ธ‰๋œ๋‹ค.
์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ•์ œ๋กœ ํ† ํฐ์„ ์žฌ์ƒ์„ฑํ•œ๋‹ค.

python manage.py drf_create_token -r <username>

์•„๋ž˜์™€ ๊ฐ™์ด ์ด์ „๊ณผ ๋‹ค๋ฅธ ํ† ํฐ์ด ์žฌ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


5. ์ƒ์„ฑ๋œ ํ† ํฐ ํš๋“ํ•˜๊ธฐ

์•„๋ž˜์™€ ๊ฐ™์ด ํ”„๋กœ์ ํŠธ ํด๋”์˜ urls.py์— obatin_auth_token๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
obtain_auth_token์€ POST๋ฐฉ์‹์˜ ์š”์ฒญ๋งŒ ๋ฐ›๋Š”๋‹ค.

from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken.views import obtain_auth_token
import userpost.urls
import rest_framework.urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('userpost/', include(userpost.urls)),
    path('api-auth/', include(rest_framework.urls)),
    path('api-token-auth/', obtain_auth_token)
]

6. httpie ๋ช…๋ น์–ด๋กœ ํ† ํฐ ํš๋“ํ•˜๊ธฐ

  • POST๋งค์„œ๋“œ๋กœ ์š”์ฒญ


  • GET๋งค์„œ๋“œ๋กœ ์š”์ฒญ


7. ํš๋“ํ•œ ํ† ํฐ์œผ๋กœ ์ธ์ฆํ•˜๊ธฐ

"Authorization: Token <Token>"์„ httpie๋ช…๋ น์–ด์— ์ถ”๊ฐ€ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

  • Request์— Token์„ ์ถ”๊ฐ€ํ•ด ๋ณด๋‚ผ ๊ฒฝ์šฐ


  • Request์— Token์ด ์—†์„ ๊ฒฝ์šฐ